From b980086d275fcb21a1233f5c9f8eb52238198b59 Mon Sep 17 00:00:00 2001
From: Aaron Bohy <aab@odoo.com>
Date: Mon, 13 Jan 2020 13:54:23 +0000
Subject: [PATCH] [FIX] web: MockServer: search_read: handle sort on many2one

Before this commit, if the records had to be sorted according a
many2one field, and there was a sequence field on the many2one
comodel, the sequence was ignored. Now, the sequence is taken into
account like the actual server does.

Linked to odoo/enterprise/pull/7407

closes odoo/odoo#43763

X-original-commit: 714e52f98eec5c64a224523cee4b1e14463ed191
Related: odoo/enterprise#7869
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
---
 .../web/static/tests/helpers/mock_server.js   | 57 ++++++++++++-------
 1 file changed, 38 insertions(+), 19 deletions(-)

diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js
index b6d9da118924..a59a925306fc 100644
--- a/addons/web/static/tests/helpers/mock_server.js
+++ b/addons/web/static/tests/helpers/mock_server.js
@@ -1028,15 +1028,7 @@ var MockServer = Class.extend({
             kwargs.orderby = kwargs.orderby.split(',')[0];
             var fieldName = kwargs.orderby.split(' ')[0];
             var order = kwargs.orderby.split(' ')[1];
-            result.sort(function (g1, g2) {
-                if (g1[fieldName] < g2[fieldName]) {
-                    return order === 'ASC' ? -1 : 1;
-                }
-                if (g1[fieldName] > g2[fieldName]) {
-                    return order === 'ASC' ? 1 : -1;
-                }
-                return 0;
-            });
+            result = this._sortByField(result, model, fieldName, order);
         }
 
         if (kwargs.limit) {
@@ -1175,19 +1167,11 @@ var MockServer = Class.extend({
             return result;
         });
         if (args.sort) {
-            // deal with sort on multiple fields (i.e. only consider the first)
+            // warning: only consider first level of sort
             args.sort = args.sort.split(',')[0];
             var fieldName = args.sort.split(' ')[0];
             var order = args.sort.split(' ')[1];
-            processedRecords.sort(function (r1, r2) {
-                if (r1[fieldName] < r2[fieldName]) {
-                    return order === 'ASC' ? -1 : 1;
-                }
-                if (r1[fieldName] > r2[fieldName]) {
-                    return order === 'ASC' ? 1 : -1;
-                }
-                return 0;
-            });
+            processedRecords = this._sortByField(processedRecords, args.model, fieldName, order);
         }
         var result = {
             length: nbRecords,
@@ -1375,6 +1359,41 @@ var MockServer = Class.extend({
 
         throw new Error("Unimplemented route: " + route);
     },
+    /**
+     * @private
+     * @param {Object[]} records the records to sort
+     * @param {string} model the model of records
+     * @param {string} fieldName the field to sort on
+     * @param {string} [order="DESC"] "ASC" or "DESC"
+     * @returns {Object}
+     */
+    _sortByField: function (records, model, fieldName, order) {
+        const field = this.data[model].fields[fieldName];
+        records.sort((r1, r2) => {
+            let v1 = r1[fieldName];
+            let v2 = r2[fieldName];
+            if (field.type === 'many2one') {
+                const coRecords = this.data[field.relation].records;
+                if (this.data[field.relation].fields.sequence) {
+                    // use sequence field of comodel to sort records
+                    v1 = coRecords.find(r => r.id === v1[0]).sequence;
+                    v2 = coRecords.find(r => r.id === v2[0]).sequence;
+                } else {
+                    // sort by id
+                    v1 = v1[0];
+                    v2 = v2[0];
+                }
+            }
+            if (v1 < v2) {
+                return order === 'ASC' ? -1 : 1;
+            }
+            if (v1 > v2) {
+                return order === 'ASC' ? 1 : -1;
+            }
+            return 0;
+        });
+        return records;
+    },
     /**
      * helper function: traverse a tree and apply the function f to each of its
      * nodes.
-- 
GitLab