From 24f3c99ab83d38b30c96f391af96cd6999fbba82 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= <tde@odoo.com>
Date: Wed, 14 Jun 2023 14:08:15 +0200
Subject: [PATCH] [FIX] base, mail: ensure ordering of search on partner / user

Add 'id' in partner ordering, to be sure searching on duplicated partners is
deterministic.

In mail, use standard ordering when searching on users to be deterministic.
As ordering on users is based on name then login which is unique, this is a
safe ordering and can be used as it.

Task-2612945 (Mail: Defensive email formatting)

Part-of: odoo/odoo#74474
---
 addons/mail/models/mail_thread.py         |  4 +-
 odoo/addons/base/models/res_partner.py    |  2 +-
 odoo/addons/base/tests/test_expression.py | 48 +++++++++++------------
 3 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py
index 43111c60a717..1cc2b8b200f9 100644
--- a/addons/mail/models/mail_thread.py
+++ b/addons/mail/models/mail_thread.py
@@ -1550,7 +1550,7 @@ class MailThread(models.AbstractModel):
         domain = [('email_normalized', 'in', normalized_emails)]
         if extra_domain:
             domain = expression.AND([domain, extra_domain])
-        partners = self.env['res.users'].sudo().search(domain, order='name ASC').mapped('partner_id')
+        partners = self.env['res.users'].sudo().search(domain).mapped('partner_id')
         # return a search on partner to filter results current user should not see (multi company for example)
         return self.env['res.partner'].search([('id', 'in', partners.ids)])
 
@@ -1608,7 +1608,7 @@ class MailThread(models.AbstractModel):
             return matching_user
 
         if not matching_user:
-            std_users = self.env['res.users'].sudo().search([('email_normalized', '=', normalized_email)], limit=1, order='name ASC')
+            std_users = self.env['res.users'].sudo().search([('email_normalized', '=', normalized_email)], limit=1)
             matching_user = std_users[0] if std_users else self.env['res.users']
         if matching_user:
             return matching_user
diff --git a/odoo/addons/base/models/res_partner.py b/odoo/addons/base/models/res_partner.py
index 101b15314dc3..f468951a0a39 100644
--- a/odoo/addons/base/models/res_partner.py
+++ b/odoo/addons/base/models/res_partner.py
@@ -134,7 +134,7 @@ class Partner(models.Model):
     _description = 'Contact'
     _inherit = ['format.address.mixin', 'image.mixin']
     _name = "res.partner"
-    _order = "display_name"
+    _order = "display_name ASC, id DESC"
 
     def _default_category(self):
         return self.env['res.partner.category'].browse(self._context.get('category_id'))
diff --git a/odoo/addons/base/tests/test_expression.py b/odoo/addons/base/tests/test_expression.py
index 5806e258f6b3..f17264ed0069 100644
--- a/odoo/addons/base/tests/test_expression.py
+++ b/odoo/addons/base/tests/test_expression.py
@@ -1086,7 +1086,7 @@ class TestQueries(TransactionCase):
                     )
                 )
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             Model.search(domain)
 
@@ -1098,7 +1098,7 @@ class TestQueries(TransactionCase):
             SELECT "res_partner".id
             FROM "res_partner"
             WHERE (("res_partner"."active" = %s) AND ("res_partner"."name"::text LIKE %s))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             Model.search([('name', 'like', 'foo')])
 
@@ -1201,7 +1201,7 @@ class TestMany2one(TransactionCase):
             SELECT "res_partner".id
             FROM "res_partner"
             WHERE ("res_partner"."company_id" = %s)
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('company_id', '=', self.company.id)])
 
@@ -1213,7 +1213,7 @@ class TestMany2one(TransactionCase):
                 FROM "res_company"
                 WHERE ("res_company"."name"::text like %s)
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('company_id.name', 'like', self.company.name)])
 
@@ -1229,7 +1229,7 @@ class TestMany2one(TransactionCase):
                     WHERE ("res_partner"."name"::text LIKE %s)
                 ))
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('company_id.partner_id.name', 'like', self.company.name)])
 
@@ -1245,7 +1245,7 @@ class TestMany2one(TransactionCase):
                 FROM "res_country"
                 WHERE ("res_country"."code"::text LIKE %s)
             )))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([
                 '|',
@@ -1264,7 +1264,7 @@ class TestMany2one(TransactionCase):
                 FROM "res_company"
                 WHERE ("res_company"."name"::text like %s)
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             company_ids = self.company._search([('name', 'like', self.company.name)], order='id')
             self.Partner.search([('company_id', 'in', company_ids)])
@@ -1280,7 +1280,7 @@ class TestMany2one(TransactionCase):
                 ORDER BY "res_company"."id"
                 LIMIT 1
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             company_ids = self.company._search([('name', 'like', self.company.name)], order='id', limit=1)
             self.Partner.search([('company_id', 'in', company_ids)])
@@ -1297,7 +1297,7 @@ class TestMany2one(TransactionCase):
             LEFT JOIN "res_company" AS "res_partner__company_id" ON
                 ("res_partner"."company_id" = "res_partner__company_id"."id")
             WHERE ("res_partner__company_id"."name"::text LIKE %s)
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('company_id.name', 'like', self.company.name)])
 
@@ -1311,7 +1311,7 @@ class TestMany2one(TransactionCase):
                 FROM "res_partner"
                 WHERE ("res_partner"."name"::text LIKE %s)
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('company_id.partner_id.name', 'like', self.company.name)])
 
@@ -1330,7 +1330,7 @@ class TestMany2one(TransactionCase):
                     ("res_company"."partner_id" = "res_company__partner_id"."id")
                 WHERE ("res_company__partner_id"."name"::text LIKE %s)
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('company_id.partner_id.name', 'like', self.company.name)])
 
@@ -1347,7 +1347,7 @@ class TestMany2one(TransactionCase):
             LEFT JOIN "res_partner" AS "res_partner__company_id__partner_id" ON
                 ("res_partner__company_id"."partner_id" = "res_partner__company_id__partner_id"."id")
             WHERE ("res_partner__company_id__partner_id"."name"::text LIKE %s)
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('company_id.partner_id.name', 'like', self.company.name)])
 
@@ -1369,7 +1369,7 @@ class TestMany2one(TransactionCase):
                 ("res_partner"."company_id" = "res_partner__company_id"."id")
             WHERE (("res_partner__company_id"."name"::text LIKE %s)
                 OR ("res_partner__country_id"."code"::text LIKE %s))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([
                 '|',
@@ -1388,7 +1388,7 @@ class TestMany2one(TransactionCase):
                 FROM "res_company"
                 WHERE ("res_company"."name"::text LIKE %s)
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('company_id', 'like', self.company.name)])
 
@@ -1417,7 +1417,7 @@ class TestOne2many(TransactionCase):
             WHERE ("res_partner"."id" IN (
                 SELECT "partner_id" FROM "res_partner_bank" WHERE "id" IN %s
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('bank_ids', 'in', self.partner.bank_ids.ids)])
 
@@ -1429,7 +1429,7 @@ class TestOne2many(TransactionCase):
                 FROM "res_partner_bank"
                 WHERE ("res_partner_bank"."sanitized_acc_number"::text LIKE %s)
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('bank_ids.sanitized_acc_number', 'like', '12')])
 
@@ -1445,7 +1445,7 @@ class TestOne2many(TransactionCase):
                     WHERE ("res_partner_bank"."sanitized_acc_number"::text LIKE %s)
                 )) AND "res_partner"."parent_id" IS NOT NULL
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('child_ids.bank_ids.sanitized_acc_number', 'like', '12')])
 
@@ -1462,7 +1462,7 @@ class TestOne2many(TransactionCase):
             WHERE ("res_partner"."id" IN (
                 SELECT "partner_id" FROM "res_partner_bank" WHERE "id" IN %s
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('bank_ids', 'in', self.partner.bank_ids.ids)])
 
@@ -1474,7 +1474,7 @@ class TestOne2many(TransactionCase):
                 FROM "res_partner_bank"
                 WHERE ("res_partner_bank"."sanitized_acc_number"::text LIKE %s)
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('bank_ids.sanitized_acc_number', 'like', '12')])
 
@@ -1490,7 +1490,7 @@ class TestOne2many(TransactionCase):
                 FROM "res_partner_bank"
                 WHERE ("res_partner_bank"."sanitized_acc_number"::text LIKE %s)
             )))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([
                 ('bank_ids.sanitized_acc_number', 'like', '12'),
@@ -1509,7 +1509,7 @@ class TestOne2many(TransactionCase):
                     WHERE ("res_partner_bank"."sanitized_acc_number"::text LIKE %s)
                 )) AND ("res_partner"."active" = %s))
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('child_ids.bank_ids.sanitized_acc_number', 'like', '12')])
 
@@ -1539,7 +1539,7 @@ class TestOne2many(TransactionCase):
                     ("res_partner"."name" != %s) OR "res_partner"."name" IS NULL
                 ))
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('child_ids.bank_ids.id', 'in', self.partner.bank_ids.ids)])
 
@@ -1565,7 +1565,7 @@ class TestOne2many(TransactionCase):
                     "res_partner"."active" = %s
                 ))
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('child_ids.state_id.country_id.code', 'like', 'US')])
 
@@ -1580,7 +1580,7 @@ class TestOne2many(TransactionCase):
                 FROM "res_partner_bank"
                 WHERE ("res_partner_bank"."sanitized_acc_number"::text LIKE %s)
             ))
-            ORDER BY "res_partner"."display_name"
+            ORDER BY "res_partner"."display_name"asc,"res_partner"."id"desc
         ''']):
             self.Partner.search([('bank_ids', 'like', '12')])
 
-- 
GitLab