From 50b94ef079b2fd9f4e9201ea8f977fadab109aea Mon Sep 17 00:00:00 2001
From: Nicolas Martinelli <nim@odoo.com>
Date: Mon, 9 May 2016 15:11:35 +0200
Subject: [PATCH] [FIX] web: search input of date

When the user searches for date (or a datetime) in the search bar, the
suggested date can become completely wrong. For example, in the French
localization where the date format is DD/MM/YYYY, the system will search
for the date MM/DD/YYYY. This is even worse when the date is not fully
written: DD/MM could be converted to MM/DD/0000, which doesn't make any
sense. This is related to the moment issue
https://github.com/moment/moment/issues/1407.

The fix is to make sure that the input date has a correct format thanks
to `parse_value`. The latter converts the date into a fixed format.

Fixes #11876
opw-676604
---
 addons/web/static/src/js/framework/formats.js   |  6 +++---
 addons/web/static/src/js/views/search_inputs.js | 12 +++++++++++-
 addons/web/static/test/search.js                |  4 +---
 3 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/addons/web/static/src/js/framework/formats.js b/addons/web/static/src/js/framework/formats.js
index 4b5ff8b4048f..52a2fa5b0b05 100644
--- a/addons/web/static/src/js/framework/formats.js
+++ b/addons/web/static/src/js/framework/formats.js
@@ -160,17 +160,17 @@ function parse_value (value, descriptor, value_if_empty) {
         case 'progressbar':
             return parse_value(value, {type: "float"});
         case 'datetime':
-            var datetime = moment(value, [date_pattern + ' ' + time_pattern, date_pattern_wo_zero + ' ' + time_pattern_wo_zero], true);
+            var datetime = moment(value, [date_pattern + ' ' + time_pattern, date_pattern_wo_zero + ' ' + time_pattern_wo_zero, moment.ISO_8601], true);
             if (datetime.isValid())
                 return time.datetime_to_str(datetime.toDate());
             throw new Error(_.str.sprintf(_t("'%s' is not a correct datetime"), value));
         case 'date':
-            var date = moment(value, [date_pattern, date_pattern_wo_zero], true);
+            var date = moment(value, [date_pattern, date_pattern_wo_zero, moment.ISO_8601], true);
             if (date.isValid())
                 return time.date_to_str(date.toDate());
             throw new Error(_.str.sprintf(_t("'%s' is not a correct date"), value));
         case 'time':
-            var _time = moment(value, [time_pattern, time_pattern_wo_zero], true);
+            var _time = moment(value, [time_pattern, time_pattern_wo_zero, moment.ISO_8601], true);
             if (_time.isValid())
                 return time.time_to_str(_time.toDate());
             throw new Error(_.str.sprintf(_t("'%s' is not a correct time"), value));
diff --git a/addons/web/static/src/js/views/search_inputs.js b/addons/web/static/src/js/views/search_inputs.js
index 9d08a537e9d3..edeffd874b08 100644
--- a/addons/web/static/src/js/views/search_inputs.js
+++ b/addons/web/static/src/js/views/search_inputs.js
@@ -341,7 +341,17 @@ var DateField = Field.extend(/** @lends instance.web.search.DateField# */{
         return time.date_to_str(facetValue.get('value'));
     },
     complete: function (needle) {
-        var m = moment(needle);
+        // Make sure the needle has a correct format before the creation of the moment object. See
+        // issue https://github.com/moment/moment/issues/1407
+        var t, v;
+        try {
+            t = (this.attrs && this.attrs.type === 'datetime') ? 'datetime' : 'date';
+            v = formats.parse_value(needle, {'widget': t});
+        } catch (e) {
+            return $.when(null);
+        }
+
+        var m = moment(v, t === 'datetime' ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD');
         if (!m.isValid()) { return $.when(null); }
         var d = m.toDate();
         var date_string = formats.format_value(d, this.attrs);
diff --git a/addons/web/static/test/search.js b/addons/web/static/test/search.js
index 4f35801cb109..d163913b0f48 100644
--- a/addons/web/static/test/search.js
+++ b/addons/web/static/test/search.js
@@ -643,7 +643,7 @@ odoo.define_section('search.completions', ['web.search_inputs', 'web.SearchView'
         var view = {inputs: []};
         var f = new DateField(
             {attrs: {string: "Dummy"}}, {type: 'datetime'}, view);
-        return f.complete('2012-05-21T21:21:21')
+        return f.complete('2012-05-21T21:21:21Z')
             .done(function (completions) {
                 assert.equal(completions.length, 1, "should provide a single completion");
                 var c = completions[0];
@@ -1615,5 +1615,3 @@ odoo.define_section('search.advanced', ['web.search_inputs', 'web.SearchView', '
     });
 
 });
-
-
-- 
GitLab