From b6f11ace836e946eeeae110cdb08d16d80546238 Mon Sep 17 00:00:00 2001 From: "Julien (juc) Castiaux" Date: Wed, 16 Jan 2019 15:26:18 +0000 Subject: [PATCH] [FIX] web: datepicker fallbacks to default english locale When using the datepicker with norwegian locales, the dates are correctly formatted using the norwegian locale but the name of the months are shown in english. This cause a date validation error and thus it is not possible to change the date. tempusdominus.js uses moment.js to deal with dates, it sometimes copies/creates some and set their option according to the ones given at instantiation time and fallbacks on default options for that are not set. opw-1922437 closes odoo/odoo#30276 --- .../web/static/src/js/widgets/date_picker.js | 1 + .../static/tests/fields/basic_fields_tests.js | 41 ++++++++++++++ .../static/tests/fields/field_utils_tests.js | 56 ++++++++++++++++++- 3 files changed, 97 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/widgets/date_picker.js b/addons/web/static/src/js/widgets/date_picker.js index b677abe377a..367ab23178d 100644 --- a/addons/web/static/src/js/widgets/date_picker.js +++ b/addons/web/static/src/js/widgets/date_picker.js @@ -25,6 +25,7 @@ var DateWidget = Widget.extend({ this.name = parent.name; this.options = _.extend({ + locale: moment.locale(), format : this.type_of_date === 'datetime' ? time.getLangDatetimeFormat() : time.getLangDateFormat(), minDate: moment({ y: 1900 }), maxDate: moment().add(200, "y"), diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js index cb49e8b5bba..978e6de226f 100644 --- a/addons/web/static/tests/fields/basic_fields_tests.js +++ b/addons/web/static/tests/fields/basic_fields_tests.js @@ -2969,6 +2969,47 @@ QUnit.module('basic_fields', { form.destroy(); }); + QUnit.test('date field support internalization', function (assert) { + assert.expect(2); + + var originalLocale = moment.locale(); + var originalParameters = _.clone(core._t.database.parameters); + + _.extend(core._t.database.parameters, {date_format: '%d. %b %Y', time_format: '%H:%M:%S'}); + moment.defineLocale('norvegianForTest', { + monthsShort: 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'), + monthsParseExact: true, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + }); + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch:'
', + res_id: 1, + }); + + var dateViewForm = form.$('.o_field_date').text(); + testUtils.dom.click(form.$buttons.find('.o_form_button_edit')); + testUtils.openDatepicker(form.$('.o_datepicker')); + assert.strictEqual(form.$('.o_datepicker_input').val(), dateViewForm, + "input date field should be the same as it was in the view form"); + + testUtils.dom.click($('.day:contains(30)')); + var dateEditForm = form.$('.o_datepicker_input').val() + testUtils.dom.click(form.$buttons.find('.o_form_button_save')); + assert.strictEqual(form.$('.o_field_date').text(), dateEditForm, + "date field should be the same as the one selected in the view form"); + + moment.locale(originalLocale); + moment.updateLocale('norvegianForTest', null); + core._t.database.parameters = originalParameters; + + form.destroy(); + }); + QUnit.module('FieldDatetime'); QUnit.test('datetime field in form view', function (assert) { diff --git a/addons/web/static/tests/fields/field_utils_tests.js b/addons/web/static/tests/fields/field_utils_tests.js index 940f5674780..c4281b38c87 100644 --- a/addons/web/static/tests/fields/field_utils_tests.js +++ b/addons/web/static/tests/fields/field_utils_tests.js @@ -297,7 +297,61 @@ QUnit.test('parse percentage', function(assert) { core._t.database.parameters = originalParameters; -}) +}); + +QUnit.test('parse datetime', function (assert) { + assert.expect(5); + + var originalParameters = _.clone(core._t.database.parameters); + var originalLocale = moment.locale(); + var dateStr, date1, date2; + + moment.defineLocale('englishForTest', { + dayOfMonthOrdinalParse: /\d{1,2}(st|nd|rd|th)/, + ordinal: function (number) { + var b = number % 10, + output = (~~(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + }, + }); + + moment.defineLocale('norvegianForTest', { + monthsShort: 'jan._feb._mars_april_mai_juni_juli_aug._sep._okt._nov._des.'.split('_'), + monthsParseExact: true, + dayOfMonthOrdinalParse: /\d{1,2}\./, + ordinal: '%d.', + }); + + moment.locale('englishForTest'); + _.extend(core._t.database.parameters, {date_format: '%m/%d/%Y', time_format: '%H:%M:%S'}); + assert.throws(function () {fieldUtils.parse.datetime("13/01/2019 12:00:00", {}, {})}, /is not a correct/, "Wrongly formated dates should be invalids"); + assert.throws(function () {fieldUtils.parse.datetime("1899-01-01 12:00:00", {}, {})}, /is not a correct/, "Dates before 1900 should be invalids"); + + dateStr = '01/13/2019 10:05:45'; + date1 = fieldUtils.parse.datetime(dateStr); + date2 = moment.utc(dateStr, ['MM/DD/YYYY HH:mm:ss'], true); + assert.equal(date1.format(), date2.format(), "Date with leading 0"); + + dateStr = '1/14/2019 10:5:45'; + date1 = fieldUtils.parse.datetime(dateStr); + date2 = moment.utc(dateStr, ['M/D/YYYY H:m:s'], true); + assert.equal(date1.format(), date2.format(), "Date without leading 0"); + + moment.locale('norvegianForTest'); + _.extend(core._t.database.parameters, {date_format: '%d. %b %Y', time_format: '%H:%M:%S'}); + dateStr = '16. jan. 2019 10:05:45'; + date1 = fieldUtils.parse.datetime(dateStr); + date2 = moment.utc(dateStr, ['DD. MMM YYYY HH:mm:ss'], true); + assert.equal(date1.format(), date2.format(), "Day/month inverted + month i18n"); + + moment.locale(originalLocale); + moment.updateLocale("englishForTest", null); + moment.updateLocale("norvegianForTest", null); + core._t.database.parameters = originalParameters; +}); }); });