Fix domain inversion of child_of mixing M2O and Reference fields
Domain inversion on Reference field does not work when using the dotted notation with a M2O field using child_of or parent_of. To solve this we correctly compute the localization of child_of leaves when using the dotted notation (which renders the inverse_leaf function useless). But we must also ensure that the selection used by reference fields restrict the choice to the right models. issue7869 review60441002
This commit is contained in:
+74
-7
@@ -638,11 +638,6 @@
|
||||
return;
|
||||
}
|
||||
var domain = field.get_domain(record);
|
||||
if (field.description.type == 'reference') {
|
||||
// The domain on reference field is not only based on the
|
||||
// selection so the selection can not be filtered.
|
||||
domain = [];
|
||||
}
|
||||
if (!('relation' in this.attributes)) {
|
||||
var change_with = this.attributes.selection_change_with || [];
|
||||
var value = record._get_on_change_args(change_with);
|
||||
@@ -707,12 +702,29 @@
|
||||
if (jQuery.isEmptyObject(domain)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var inversion = new Sao.common.DomainInversion();
|
||||
this.selection = this.selection.filter(function(value) {
|
||||
var _value_evaluator = function(value) {
|
||||
var context = {};
|
||||
context[this.field_name] = value[0];
|
||||
return inversion.eval_domain(domain, context);
|
||||
}.bind(this));
|
||||
}.bind(this);
|
||||
|
||||
var _model_evaluator = function(allowed_models) {
|
||||
return function(value) {
|
||||
return allowed_models.includes(value[0]);
|
||||
};
|
||||
};
|
||||
|
||||
var evaluator;
|
||||
if (field.description.type == 'reference') {
|
||||
var allowed_models = field.get_models(record);
|
||||
evaluator = _model_evaluator(allowed_models);
|
||||
} else {
|
||||
evaluator = _value_evaluator;
|
||||
}
|
||||
|
||||
this.selection = this.selection.filter(evaluator);
|
||||
};
|
||||
Sao.common.selection_mixin.get_inactive_selection = function(value) {
|
||||
if (!this.attributes.relation) {
|
||||
@@ -2199,6 +2211,10 @@
|
||||
return domain;
|
||||
} else if (this.is_leaf(domain)) {
|
||||
if (domain[1].contains('child_of')) {
|
||||
if (domain[0].split('.').length > 1) {
|
||||
var target = domain[0].split('.').slice(1).join('.');
|
||||
return [target].concat(domain.slice(1));
|
||||
}
|
||||
if (domain.length == 3) {
|
||||
return domain;
|
||||
} else {
|
||||
@@ -2218,6 +2234,57 @@
|
||||
}.bind(this));
|
||||
}
|
||||
},
|
||||
prepare_reference_domain: function(domain, reference) {
|
||||
if (~['AND', 'OR'].indexOf(domain)) {
|
||||
return domain;
|
||||
} else if (this.is_leaf(domain)) {
|
||||
if ((domain[0].split('.').length > 1) &&
|
||||
(domain.length > 3)) {
|
||||
var parts = domain[0].split('.');
|
||||
var local_name = parts[0];
|
||||
var target_name = parts.slice(1).join('.');
|
||||
|
||||
if (local_name == reference) {
|
||||
var where = [];
|
||||
where.push(target_name);
|
||||
where = where.concat(
|
||||
domain.slice(1, 3), domain.slice(4));
|
||||
return where;
|
||||
}
|
||||
return domain;
|
||||
}
|
||||
return domain;
|
||||
} else {
|
||||
return domain.map(function(d) {
|
||||
return this.prepare_reference_domain(d, reference);
|
||||
}.bind(this));
|
||||
}
|
||||
},
|
||||
extract_reference_models: function(domain, field_name) {
|
||||
if (~['AND', 'OR'].indexOf(domain)) {
|
||||
return [];
|
||||
} else if (this.is_leaf(domain)) {
|
||||
var local_part = domain[0].split('.', 1)[0];
|
||||
if ((local_part == field_name) &&
|
||||
(domain.length > 3)) {
|
||||
return [domain[3]];
|
||||
}
|
||||
return [];
|
||||
} else {
|
||||
var models = [];
|
||||
domain.map(function(d) {
|
||||
var new_models = this.extract_reference_models(
|
||||
d, field_name);
|
||||
for (var i=0, len=new_models.length; i < len; i++) {
|
||||
var model = new_models[i];
|
||||
if (!models.includes(model)) {
|
||||
models.push(model);
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
return models;
|
||||
}
|
||||
},
|
||||
simplify: function(domain) {
|
||||
if (this.is_leaf(domain)) {
|
||||
return domain;
|
||||
|
||||
+13
-4
@@ -1911,8 +1911,8 @@
|
||||
var screen_domain = domains[0];
|
||||
var attr_domain = domains[1];
|
||||
var inversion = new Sao.common.DomainInversion();
|
||||
return inversion.concat([inversion.localize_domain(
|
||||
inversion.inverse_leaf(screen_domain), this.name),
|
||||
return inversion.concat([
|
||||
inversion.localize_domain(screen_domain, this.name),
|
||||
attr_domain]);
|
||||
},
|
||||
get_on_change_value: function(record) {
|
||||
@@ -2442,10 +2442,19 @@
|
||||
var screen_domain = domains[0];
|
||||
var attr_domain = domains[1];
|
||||
var inversion = new Sao.common.DomainInversion();
|
||||
screen_domain = inversion.prepare_reference_domain(
|
||||
screen_domain, this.name);
|
||||
return inversion.concat([inversion.localize_domain(
|
||||
inversion.filter_leaf(screen_domain, this.name, model),
|
||||
true), attr_domain]);
|
||||
},
|
||||
get_models: function(record) {
|
||||
var domains = this.get_domains(record);
|
||||
var inversion = new Sao.common.DomainInversion();
|
||||
return inversion.extract_reference_models(
|
||||
inversion.concat(domains[0], domains[1]),
|
||||
this.name);
|
||||
},
|
||||
_is_empty: function(record) {
|
||||
var result = Sao.field.Reference._super._is_empty.call(
|
||||
this, record);
|
||||
@@ -2522,8 +2531,8 @@
|
||||
var domains = this.get_domains(record);
|
||||
var screen_domain = domains[0];
|
||||
var attr_domain = domains[1];
|
||||
return inversion.concat([inversion.localize_domain(
|
||||
inversion.inverse_leaf(screen_domain)),
|
||||
return inversion.concat([
|
||||
inversion.localize_domain(screen_domain),
|
||||
attr_domain]);
|
||||
},
|
||||
date_format: function(record) {
|
||||
|
||||
@@ -2344,6 +2344,18 @@
|
||||
[['x', 'child_of', [1]]]),
|
||||
'localize_domain(' + JSON.stringify(domain) + ', \'x\')');
|
||||
|
||||
domain = [['x.y', 'child_of', [1], 'parent']];
|
||||
QUnit.ok(compare(
|
||||
localize_domain(domain, 'x'),
|
||||
[['y', 'child_of', [1], 'parent']]),
|
||||
'localize_domain(' + JSON.stringify(domain) + ', \'x\')');
|
||||
|
||||
domain = [['x.y.z', 'child_of', [1], 'parent', 'model']];
|
||||
QUnit.ok(compare(
|
||||
localize_domain(domain, 'x'),
|
||||
[['y.z', 'child_of', [1], 'parent', 'model']]),
|
||||
'localize_domain(' + JSON.stringify(domain) + ', \'x\')');
|
||||
|
||||
domain = [['x', 'child_of', [1], 'y']];
|
||||
QUnit.ok(compare(localize_domain(domain, 'x'),
|
||||
[['y', 'child_of', [1]]]),
|
||||
@@ -2367,6 +2379,62 @@
|
||||
|
||||
});
|
||||
|
||||
QUnit.test('DomainInversion.prepare_reference_domain', function() {
|
||||
var domain_inversion = new Sao.common.DomainInversion();
|
||||
var prepare_reference_domain = domain_inversion
|
||||
.prepare_reference_domain.bind(domain_inversion);
|
||||
var compare = Sao.common.compare;
|
||||
|
||||
var domain = [['x', 'like', 'A%']];
|
||||
QUnit.ok(compare(
|
||||
prepare_reference_domain(domain, 'x'),
|
||||
[['x', 'like', 'A%']]));
|
||||
|
||||
domain = [['x.y', 'like', 'A%', 'model']];
|
||||
QUnit.ok(compare(
|
||||
prepare_reference_domain(domain, 'x'),
|
||||
[['y', 'like', 'A%']]));
|
||||
|
||||
domain = [['x.y', 'child_of', [1], 'model', 'parent']];
|
||||
QUnit.ok(compare(
|
||||
prepare_reference_domain(domain, 'x'),
|
||||
[['y', 'child_of', [1], 'parent']]));
|
||||
});
|
||||
|
||||
QUnit.test('DomainInversion.extract_reference_models', function() {
|
||||
var domain_inversion = new Sao.common.DomainInversion();
|
||||
var extract_models = domain_inversion
|
||||
.extract_reference_models.bind(domain_inversion);
|
||||
var compare = Sao.common.compare;
|
||||
|
||||
var domain = [['x', 'like', 'A%']];
|
||||
QUnit.ok(compare(
|
||||
extract_reference_models(domain, 'x'),
|
||||
[]));
|
||||
QUnit.ok(compare(
|
||||
extract_reference_models(domain, 'y'),
|
||||
[]));
|
||||
|
||||
domain = [['x', 'like', 'A%', 'model']];
|
||||
QUnit.ok(compare(
|
||||
extract_reference_models(domain, 'x'),
|
||||
['model']));
|
||||
QUnit.ok(compare(
|
||||
extract_reference_models(domain, 'y'),
|
||||
[]));
|
||||
|
||||
domain = ['OR',
|
||||
['x', 'like', 'A%', 'model_A'],
|
||||
['x', 'like', 'B%', 'model_B']
|
||||
];
|
||||
QUnit.ok(compare(
|
||||
extract_reference_models(domain, 'x'),
|
||||
['model_A', 'model_B']));
|
||||
QUnit.ok(compare(
|
||||
extract_reference_models(domain, 'y'),
|
||||
[]));
|
||||
});
|
||||
|
||||
QUnit.test('DomainParser.completion', function() {
|
||||
var compare = Sao.common.compare;
|
||||
var parser = new Sao.common.DomainParser({
|
||||
|
||||
Reference in New Issue
Block a user