summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2017-03-31 14:18:22 +0200
committerAaron Bohy <aab@odoo.com>2017-04-11 19:44:38 +0200
commitb9d9c6e3bc8d3fd4bb547aadf002652bb7bb9db4 (patch)
tree6ce9dadcaa09811f69afeee604b9d3d97fc92ba8
parentc5d5d7a0ff05d1664e50e5239e5b5efa77a032f6 (diff)
[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.
-rw-r--r--addons/web/static/src/js/fields/abstract_field.js6
-rw-r--r--addons/web/static/src/js/fields/basic_fields.js49
-rw-r--r--addons/web/static/src/js/fields/field_utils.js55
-rw-r--r--addons/web/static/src/js/views/form/form_renderer.js2
-rw-r--r--addons/web/static/test/fields/basic_fields_tests.js12
5 files changed, 91 insertions, 33 deletions
diff --git a/addons/web/static/src/js/fields/abstract_field.js b/addons/web/static/src/js/fields/abstract_field.js
index 6eac12a2dba..79583894fdc 100644
--- a/addons/web/static/src/js/fields/abstract_field.js
+++ b/addons/web/static/src/js/fields/abstract_field.js
@@ -50,6 +50,12 @@ var AbstractField = Widget.extend({
*/
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
*/
replace_element: false,
diff --git a/addons/web/static/src/js/fields/basic_fields.js b/addons/web/static/src/js/fields/basic_fields.js
index ffba3158d43..1b96d585ac7 100644
--- a/addons/web/static/src/js/fields/basic_fields.js
+++ b/addons/web/static/src/js/fields/basic_fields.js
@@ -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,
+ });
},
});
diff --git a/addons/web/static/src/js/fields/field_utils.js b/addons/web/static/src/js/fields/field_utils.js
index cc9580c4baf..e529e6080d6 100644
--- a/addons/web/static/src/js/fields/field_utils.js
+++ b/addons/web/static/src/js/fields/field_utils.js
@@ -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 = 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 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 formatted_value = formatFloat(value, field, {
+ digits: (currency && currency.digits) || options.digits,
+ });
if (!currency) {
return formatted_value;
diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js
index f417b53885d..0212832929c 100644
--- a/addons/web/static/src/js/views/form/form_renderer.js
+++ b/addons/web/static/src/js/views/form/form_renderer.js
@@ -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));
}
});
diff --git a/addons/web/static/test/fields/basic_fields_tests.js b/addons/web/static/test/fields/basic_fields_tests.js
index 8cea1900c7c..c56f694e1fe 100644
--- a/addons/web/static/test/fields/basic_fields_tests.js
+++ b/addons/web/static/test/fields/basic_fields_tests.js
@@ -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();
});