[FIX] web: properly evaluate unset numeric values in domain
Before this commit, when a numeric value was not set (for example, a new record with no default_get value), then it was not properly evaluated as 0 in a domain. We also slightly refactored the code so we always use the same method to compute the evaluation context.
This commit is contained in:
committed by
Aaron Bohy
parent
a529a928b4
commit
3ff7ff3e94
@@ -268,6 +268,8 @@ var BasicModel = AbstractModel.extend({
|
||||
* @param {boolean} [options.env=false] if true, will only return res_id
|
||||
* (if record) or res_ids (if list)
|
||||
* @param {boolean} [options.raw=false] if true, will not follow relations
|
||||
* @param {boolean} [options.noUnsetNumeric=false] if true, will set numeric
|
||||
* values to 0 if not set
|
||||
* @returns {Object}
|
||||
*/
|
||||
get: function (id, options) {
|
||||
@@ -311,6 +313,13 @@ var BasicModel = AbstractModel.extend({
|
||||
if (!field) {
|
||||
continue;
|
||||
}
|
||||
if (options.noUnsetNumeric) {
|
||||
if (field.type === 'float' ||
|
||||
field.type === 'integer' ||
|
||||
field.type === 'monetary') {
|
||||
element.data[fieldName] = element.data[fieldName] || 0;
|
||||
}
|
||||
}
|
||||
|
||||
// get relational datapoint
|
||||
if (field.type === 'many2one') {
|
||||
@@ -1792,7 +1801,7 @@ var BasicModel = AbstractModel.extend({
|
||||
* @returns {Object}
|
||||
*/
|
||||
_getEvalContext: function (element) {
|
||||
var evalContext = this.get(element.id, {raw: true}).data;
|
||||
var evalContext = this.get(element.id, {raw: true, noUnsetNumeric: true}).data;
|
||||
evalContext.active_model = element.model;
|
||||
if (evalContext.id) {
|
||||
evalContext.active_id = evalContext.id;
|
||||
|
||||
@@ -51,44 +51,6 @@ return AbstractRenderer.extend({
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Helper method, used to get an object with the 'raw' field values. It is
|
||||
* important when we want to evaluate if a record matches a given domain.
|
||||
*
|
||||
* A basic model record is a tree structure, but we sometimes need 'pure'
|
||||
* data, so for example, [1,4] for the value of a one2many, not
|
||||
* [{Object}, {Object}].
|
||||
*
|
||||
* @param {Object} record
|
||||
* @returns {Object}
|
||||
*/
|
||||
_getFieldValues: function (record) {
|
||||
var result = {};
|
||||
_.each(record.getFieldNames(), function (name) {
|
||||
var field = record.fields[name];
|
||||
var value = record.data[name];
|
||||
result[name] = value;
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
else if (field.type === 'many2one') {
|
||||
result[name] = value.data ? value.data.id || false : false;
|
||||
}
|
||||
else if (field.type === 'one2many' || field.type === 'many2many') {
|
||||
if (value) {
|
||||
result[name] = _.pluck(value.data, 'res_id');
|
||||
} else {
|
||||
result[name] = [];
|
||||
}
|
||||
}
|
||||
else if (field.type === 'boolean') {
|
||||
// we want an explicit false value, not null if it is unset
|
||||
result[name] = value || false;
|
||||
}
|
||||
});
|
||||
result.id = record.data.id;
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* Render the view
|
||||
*
|
||||
|
||||
@@ -29,7 +29,7 @@ return BasicRenderer.extend({
|
||||
this.idsForLabels = {};
|
||||
this.widgets = [];
|
||||
this.mode = params.mode;
|
||||
this.field_values = this._getFieldValues(this.state);
|
||||
this.field_values = this.state.getEvalContext();
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -136,7 +136,7 @@ return BasicRenderer.extend({
|
||||
// only update the given fields
|
||||
return this.updateWidgets(params.fieldNames, state);
|
||||
}
|
||||
this.field_values = this._getFieldValues(state);
|
||||
this.field_values = state.getEvalContext();
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
/**
|
||||
@@ -152,7 +152,7 @@ return BasicRenderer.extend({
|
||||
*/
|
||||
updateWidgets: function (fields, state, event) {
|
||||
this.state = state;
|
||||
this.field_values = this._getFieldValues(this.state);
|
||||
this.field_values = this.state.getEvalContext();
|
||||
var defs = [];
|
||||
_.each(this.widgets, function (widget) {
|
||||
if (_.contains(fields, widget.name) || widget.resetOnAnyFieldChange) {
|
||||
|
||||
@@ -215,7 +215,7 @@ ListRenderer.include({
|
||||
return true;
|
||||
}
|
||||
if ('readonly' in node.modifiers) {
|
||||
var fieldValues = this._getFieldValues(record);
|
||||
var fieldValues = record.getEvalContext();
|
||||
return new Domain(node.modifiers.readonly).compute(fieldValues);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -223,7 +223,7 @@ var ListRenderer = BasicRenderer.extend({
|
||||
*/
|
||||
_isInvisible: function (record, node) {
|
||||
if ('invisible' in node.modifiers) {
|
||||
var fieldValues = this._getFieldValues(record);
|
||||
var fieldValues = record.getEvalContext();
|
||||
return new Domain(node.modifiers.invisible).compute(fieldValues);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -363,6 +363,31 @@ QUnit.module('Views', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('invisible attrs with zero value in domain and unset value in data', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
this.data.partner.fields.int_field.type = 'monetary';
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form string="Partners">' +
|
||||
'<sheet>' +
|
||||
'<field name="foo"/>' +
|
||||
'<group attrs=\'{"invisible": [["int_field", "=", 0.0]]}\'>' +
|
||||
'<div class="hello">this should be invisible</div>' +
|
||||
'<field name="int_field"/>' +
|
||||
'</group>' +
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
});
|
||||
|
||||
assert.notOk(form.$('div.hello').is(':visible'),
|
||||
"attrs invisible should have been computed and applied");
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('rendering stat buttons', function (assert) {
|
||||
assert.expect(3);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user