summaryrefslogtreecommitdiff
path: root/addons/web/static
diff options
context:
space:
mode:
authorAdrien Dieudonne <adr@odoo.com>2017-08-16 13:21:54 +0200
committerAaron Bohy <aab@odoo.com>2017-08-17 17:24:00 +0200
commitb9bfec96dd038d23e26cc822560fee452a0a3271 (patch)
tree47c6c74a934e86ce01839122a2fb7dcf552cf913 /addons/web/static
parent88dfcfd025ad87476d27cb7122cedc9ab2e94d3c (diff)
[FIX] web: don't apply timezone offset for date fields
Before this rev., all date fields values were off by one day as soon as the user timezone was negative. With the new views, all dates manipulated by the JS are moment instances in UTC, and when being displayed, they are correctly formatted in the user locale by applying the timezone offset. However, this should obviously not be done for date fields as when no time is specified when creating a moment instance, it defaults to 00:00:00, so applying a negative offset always leads to the day before. Remark: It happens that datetime fields are displayed as a date (e.g. purchase order line form view). In that case, the offset is applied on the displayed date.
Diffstat (limited to 'addons/web/static')
-rw-r--r--addons/web/static/src/js/fields/field_utils.js11
-rw-r--r--addons/web/static/src/js/fields/special_fields.js2
-rw-r--r--addons/web/static/tests/fields/basic_fields_tests.js115
-rw-r--r--addons/web/static/tests/fields/field_utils_tests.js2
4 files changed, 120 insertions, 10 deletions
diff --git a/addons/web/static/src/js/fields/field_utils.js b/addons/web/static/src/js/fields/field_utils.js
index 0a44a52e315..787f66080dd 100644
--- a/addons/web/static/src/js/fields/field_utils.js
+++ b/addons/web/static/src/js/fields/field_utils.js
@@ -95,8 +95,10 @@ function formatDate(value, field, options) {
if (value === false) {
return "";
}
- if (!options || !('timezone' in options) || options.timezone) {
- value = value.clone().add(session.tzOffset < 0 ? -1 : 0, 'days');
+ if (field && field.type === 'datetime') {
+ if (!options || !('timezone' in options) || options.timezone) {
+ value = value.clone().add(session.tzOffset, 'minutes');
+ }
}
var l10n = core._t.database.parameters;
var date_format = time.strftime_to_moment_format(l10n.date_format);
@@ -357,11 +359,8 @@ function parseDate(value, field, options) {
date = moment.utc(value);
} else {
date = moment.utc(value, [datePattern, datePatternWoZero, moment.ISO_8601], true);
- if (options && options.timezone) {
- date.add(session.tzOffset > 0 ? -1 : 0, 'days');
- }
}
- if (date.isValid() && date.year() >= 1900) {
+ if (date.isValid()) {
if (date.year() === 0) {
date.year(moment.utc().year());
}
diff --git a/addons/web/static/src/js/fields/special_fields.js b/addons/web/static/src/js/fields/special_fields.js
index 69647902afe..7a0bb9ed092 100644
--- a/addons/web/static/src/js/fields/special_fields.js
+++ b/addons/web/static/src/js/fields/special_fields.js
@@ -54,7 +54,7 @@ var FieldTimezoneMismatch = FieldSelection.extend({
}
var offset = this.recordData.tz_offset.match(/([+-])([0-9]{2})([0-9]{2})/);
offset = (offset[1] === '-' ? -1 : 1) * (parseInt(offset[2])*60 + parseInt(offset[3]));
- var datetime = field_utils.format.datetime(moment.utc().add(offset, 'minutes'), {timezone: false});
+ var datetime = field_utils.format.datetime(moment.utc().add(offset, 'minutes'), this.field, {timezone: false});
var content = this.$option.html().split(' ')[0];
content += ' ('+ datetime + ')';
this.$option.html(content);
diff --git a/addons/web/static/tests/fields/basic_fields_tests.js b/addons/web/static/tests/fields/basic_fields_tests.js
index 0be9bed3fa9..a1aa5958009 100644
--- a/addons/web/static/tests/fields/basic_fields_tests.js
+++ b/addons/web/static/tests/fields/basic_fields_tests.js
@@ -1570,7 +1570,7 @@ QUnit.module('basic_fields', {
form.destroy();
});
- QUnit.test('date field in form view', function (assert) {
+ QUnit.test('date field in form view (with positive time zone offset)', function (assert) {
assert.expect(8);
var form = createView({
@@ -1589,7 +1589,7 @@ QUnit.module('basic_fields', {
date_format: '%m/%d/%Y',
},
session: {
- tzOffset: 120
+ tzOffset: 120 // Should be ignored by date fields
},
});
@@ -1621,6 +1621,34 @@ QUnit.module('basic_fields', {
form.destroy();
});
+ QUnit.test('date field in form view (with negative time zone offset)', function (assert) {
+ assert.expect(2);
+
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch:'<form string="Partners"><field name="date"/></form>',
+ res_id: 1,
+ translateParameters: { // Avoid issues due to localization formats
+ date_format: '%m/%d/%Y',
+ },
+ session: {
+ tzOffset: -120 // Should be ignored by date fields
+ },
+ });
+
+ assert.strictEqual(form.$('.o_field_date').text(), '02/03/2017',
+ 'the date should be correctly displayed in readonly');
+
+ // switch to edit mode
+ form.$buttons.find('.o_form_button_edit').click();
+ assert.strictEqual(form.$('.o_datepicker_input').val(), '02/03/2017',
+ 'the date should be correct in edit mode');
+
+ form.destroy();
+ });
+
QUnit.test('date field in editable list view', function (assert) {
assert.expect(8);
@@ -1870,6 +1898,89 @@ QUnit.module('basic_fields', {
form.destroy();
});
+ QUnit.test('datetime field with date/datetime widget (with day change)', function (assert) {
+ assert.expect(2);
+
+ this.data.partner.records[0].p = [2];
+ this.data.partner.records[1].datetime = "2017-02-08 02:00:00"; // UTC
+
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch:'<form string="Partners">' +
+ '<field name="p">' +
+ '<tree>' +
+ '<field name="datetime"/>' +
+ '</tree>' +
+ '<form>' +
+ '<field name="datetime" widget="date"/>' +
+ '</form>' +
+ '</field>' +
+ '</form>',
+ res_id: 1,
+ translateParameters: { // Avoid issues due to localization formats
+ date_format: '%m/%d/%Y',
+ time_format: '%H:%M:%S',
+ },
+ session: {
+ tzOffset: -240,
+ },
+ });
+
+ var expectedDateString = "02/07/2017 22:00:00"; // local time zone
+ assert.strictEqual(form.$('.o_field_widget[name=p] .o_data_cell').text(), expectedDateString,
+ 'the datetime (datetime widget) should be correctly displayed in tree view');
+
+ // switch to form view
+ form.$('.o_field_widget[name=p] .o_data_row').click();
+ assert.strictEqual($('.modal .o_field_date[name=datetime]').text(), '02/07/2017',
+ 'the datetime (date widget) should be correctly displayed in form view');
+
+ form.destroy();
+ });
+
+ QUnit.test('datetime field with date/datetime widget (without day change)', function (assert) {
+ assert.expect(2);
+
+ this.data.partner.records[0].p = [2];
+ this.data.partner.records[1].datetime = "2017-02-08 10:00:00"; // without timezone
+
+ var form = createView({
+ View: FormView,
+ model: 'partner',
+ data: this.data,
+ arch:'<form string="Partners">' +
+ '<field name="p">' +
+ '<tree>' +
+ '<field name="datetime"/>' +
+ '</tree>' +
+ '<form>' +
+ '<field name="datetime" widget="date"/>' +
+ '</form>' +
+ '</field>' +
+ '</form>',
+ res_id: 1,
+ translateParameters: { // Avoid issues due to localization formats
+ date_format: '%m/%d/%Y',
+ time_format: '%H:%M:%S',
+ },
+ session: {
+ tzOffset: -240,
+ },
+ });
+
+ var expectedDateString = "02/08/2017 06:00:00"; // with timezone
+ assert.strictEqual(form.$('.o_field_widget[name=p] .o_data_cell').text(), expectedDateString,
+ 'the datetime (datetime widget) should be correctly displayed in tree view');
+
+ // switch to form view
+ form.$('.o_field_widget[name=p] .o_data_row').click();
+ assert.strictEqual($('.modal .o_field_date[name=datetime]').text(), '02/08/2017',
+ 'the datetime (date widget) should be correctly displayed in form view');
+
+ form.destroy();
+ });
QUnit.module('FieldMonetary');
diff --git a/addons/web/static/tests/fields/field_utils_tests.js b/addons/web/static/tests/fields/field_utils_tests.js
index a49197f6e65..922c9f3a79c 100644
--- a/addons/web/static/tests/fields/field_utils_tests.js
+++ b/addons/web/static/tests/fields/field_utils_tests.js
@@ -59,7 +59,7 @@ QUnit.test("format_datetime", function (assert) {
var date_string = "2009-05-04 12:34:23";
var date = fieldUtils.parse.datetime(date_string, {}, {timezone: false});
- var str = fieldUtils.format.datetime(date, {timezone: false});
+ var str = fieldUtils.format.datetime(date, {}, {timezone: false});
assert.strictEqual(str, moment(date).format("MM/DD/YYYY HH:mm:ss"));
});