[FIX] web: monetary should reset on currency change

This reverts commit 839a07fbed4720fc71c070507c591295722df350.
Indeed, the system will need the `resetOnAnyFieldChange` option as the
`FieldMonetary` will need to be re-rendered if the currency changes.
This does not use the `_fetchSpecialData` system as it will be
refactored later and the currency can be fetched without RPC.
This commit is contained in:
qsm-odoo
2017-04-11 19:44:38 +02:00
committed by Aaron Bohy
parent c5d5d7a0ff
commit b9d9c6e3bc
5 changed files with 92 additions and 34 deletions
@@ -49,6 +49,12 @@ var AbstractField = Widget.extend({
* skip the widget when pressing tab
*/
readonly: false,
/**
* If this flag is set to true, the field widget will be reset on every
* change which is made in the view (if the view supports it). This is
* currently a form view feature.
*/
resetOnAnyFieldChange: false,
/**
* if true, the widget will replace a cell in an editable list view
*/
+32 -17
View File
@@ -313,6 +313,7 @@ var FieldMonetary = InputField.extend({
className: 'o_form_field_monetary o_list_number',
replace_element: true,
supportedFieldTypes: ['float', 'monetary'],
resetOnAnyFieldChange: true, // Have to listen to currency changes
/**
* Float fields using a monetary widget have an additional currency_field
@@ -331,18 +332,9 @@ var FieldMonetary = InputField.extend({
init: function () {
this._super.apply(this, arguments);
// Options for _formatValue
this.nodeOptions.digits = [16,2];
if (this.attrs.currency_field) {
this.nodeOptions.currency_field = this.attrs.currency_field;
} else {
this.nodeOptions.currency_field = this.field.currency_field || 'currency_id';
}
if (this.record.data[this.nodeOptions.currency_field]) {
this.nodeOptions.currency_id = this.record.data[this.nodeOptions.currency_field].res_id;
}
this._setCurrency();
if (this.mode === 'edit' && this.nodeOptions.currency_id) {
if (this.mode === 'edit' && this.currency) {
this.tagName = 'div';
}
},
@@ -372,7 +364,7 @@ var FieldMonetary = InputField.extend({
* @private
*/
_renderEdit: function () {
if (!this.nodeOptions.currency_id) {
if (!this.currency) {
this._super.apply(this, arguments);
return;
}
@@ -381,15 +373,35 @@ var FieldMonetary = InputField.extend({
// Prepare and add the input
this._prepareInput().appendTo(this.$el);
// prepare and add the currency symbol
var currency = session.get_currency(this.nodeOptions.currency_id);
var $currencySymbol = $('<span>', {text: currency.symbol});
if (currency.position === "after") {
var $currencySymbol = $('<span>', {text: this.currency.symbol});
if (this.currency.position === "after") {
this.$el.append($currencySymbol);
} else {
this.$el.prepend($currencySymbol);
}
},
/**
* Re-gets the currency as its value may have changed.
* @see FieldMonetary.resetOnAnyFieldChange
*
* @override
* @private
*/
_reset: function () {
this._super.apply(this, arguments);
this._setCurrency();
},
/**
* Deduces the currency description from the field options and view state.
* The description is then available at this.currency.
*
* @private
*/
_setCurrency: function () {
var currencyField = this.attrs.currency_field || this.field.currency_field || 'currency_id';
var currencyID = this.record.data[currencyField] && this.record.data[currencyField].res_id;
this.currency = session.get_currency(currencyID);
},
/**
* FieldMonetary overrides _formatValue to use the format monetary method
* in readonly.
@@ -400,7 +412,10 @@ var FieldMonetary = InputField.extend({
*/
_formatValue: function (value) {
var format = field_utils.format[this.mode === 'edit' ? "float" : "monetary"];
return format(value, this.field, this.nodeOptions);
return format(value, this.field, {
digits: [16, 2],
currency: this.currency,
});
},
});
+43 -14
View File
@@ -100,8 +100,8 @@ function formatDateTime(value) {
* should be used.
* @param {Object} [options] additional options to override the values in the
* python description of the field.
* @param {integer} [options.digit] the number of digit that should be used,
* instead of the default digit precision in the field.
* @param {integer[]} [options.digits] the number of digits that should be used,
* instead of the default digits precision in the field.
* @returns {string}
*/
function formatFloat(value, field, options) {
@@ -191,21 +191,50 @@ function formatMany2Many(value) {
}
}
/**
* Returns a string representing a monetary value. The result takes into account
* the user settings (to display the correct decimal separator, currency, ...).
*
* @param {float} value the value that should be formatted
* @param {Object} [field]
* a description of the field (returned by fields_get for example). It
* may contain a description of the number of digits that should be used.
* @param {Object} [options]
* additional options to override the values in the python description of
* the field.
* @param {Object} [options.currency] - the description of the currency to use
* @param {integer} [options.currency_id]
* the id of the 'res.currency' to use (ignored if options.currency)
* @param {string} [options.currency_field]
* the name of the field whose value is the currency id
* (ignore if options.currency or options.currency_id)
* Note: if not given it will default to the field currency_field value
* or to 'currency_id'.
* @param {Object} [options.data]
* a mapping of field name to field value, required with
* options.currency_field
* @param {integer[]} [options.digits]
* the number of digits that should be used, instead of the default
* digits precision in the field. Note: if the currency defines a
* precision, the currency's one is used.
* @returns {string}
*/
function formatMonetary(value, field, options) {
options = options || {};
var currency_id = options.currency_id;
if (!currency_id && options.data) {
var currency_field = options.currency_field || field.currency_field || 'currency_id';
currency_id = options.data[currency_field] && options.data[currency_field].res_id;
}
var currency = session.get_currency(currency_id);
var digits_precision = (currency && currency.digits) || [69,2];
var precision = digits_precision[1];
var formatted = _.str.sprintf('%.' + precision + 'f', value || 0).split('.');
formatted[0] = utils.insert_thousand_seps(formatted[0]);
var l10n = core._t.database.parameters;
var formatted_value = formatted.join(l10n.decimal_point);
var currency = options.currency;
if (!currency) {
var currency_id = options.currency_id;
if (!currency_id && options.data) {
var currency_field = options.currency_field || field.currency_field || 'currency_id';
currency_id = options.data[currency_field] && options.data[currency_field].res_id;
}
currency = session.get_currency(currency_id);
}
var formatted_value = formatFloat(value, field, {
digits: (currency && currency.digits) || options.digits,
});
if (!currency) {
return formatted_value;
@@ -155,7 +155,7 @@ return BasicRenderer.extend({
this.field_values = this._getFieldValues(this.state);
var defs = [];
_.each(this.widgets, function (widget) {
if (_.contains(fields, widget.name)) {
if (_.contains(fields, widget.name) || widget.resetOnAnyFieldChange) {
defs.push(widget.reset(state, event));
}
});
@@ -100,10 +100,12 @@ QUnit.module('basic_fields', {
},
records: [{
id: 1,
display_name: "$",
symbol: "$",
position: "before",
}, {
id: 2,
display_name: "€",
symbol: "€",
position: "after",
}]
@@ -1333,7 +1335,7 @@ QUnit.module('basic_fields', {
});
QUnit.test('monetary field with real monetary field in model', function (assert) {
assert.expect(3);
assert.expect(4);
this.data.partner.fields.qux.type = "monetary";
@@ -1350,7 +1352,7 @@ QUnit.module('basic_fields', {
arch:'<form string="Partners">' +
'<sheet>' +
'<field name="qux"/>' +
'<field name="currency_id" invisible="1"/>' +
'<field name="currency_id"/>' +
'<field name="bar"/>' +
'</sheet>' +
'</form>',
@@ -1372,6 +1374,12 @@ QUnit.module('basic_fields', {
assert.strictEqual(form.$('.o_form_field_monetary > input').length, 1,
"After the onchange, the monetary <input/> should not have been duplicated");
var $dropdown = form.$('.o_form_field_many2one input').autocomplete('widget');
form.$('.o_form_field_many2one input').click();
$dropdown.find('li:not(.o_m2o_dropdown_option):last').mouseenter().click();
assert.strictEqual(form.$('.o_form_field_monetary > span').html(), "€",
"After currency change, the monetary field currency should have been updated");
form.destroy();
});