From ceace63df5787f8dbad6ce85c008886c7c8cdf59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sat, 13 Jul 2024 15:35:01 +0200 Subject: [PATCH] Cast numeric columns for order expression on SQLite Closes #13397 (grafted from 97e889240413ac521a15dc81453499bb888039c0) --HG-- branch : 7.0 --- trytond/trytond/model/fields/numeric.py | 9 +++++++++ trytond/trytond/tests/test_field_numeric.py | 22 +++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/trytond/trytond/model/fields/numeric.py b/trytond/trytond/model/fields/numeric.py index da32460301..b99d4e4ac6 100644 --- a/trytond/trytond/model/fields/numeric.py +++ b/trytond/trytond/model/fields/numeric.py @@ -6,6 +6,7 @@ from sql import Cast, CombiningQuery, Literal, Select from trytond import backend +from .field import order_method from .float import Float @@ -17,6 +18,14 @@ class Numeric(Float): _sql_type = 'NUMERIC' _py_type = Decimal + @order_method + def convert_order(self, name, tables, Model): + columns = super().convert_order(name, tables, Model) + if backend.name == 'sqlite': + # Must be cast because Decimal is stored as bytes + columns = [Cast(c, self.sql_type().base) for c in columns] + return columns + def _domain_column(self, operator, column): column = super()._domain_column(operator, column) if backend.name == 'sqlite': diff --git a/trytond/trytond/tests/test_field_numeric.py b/trytond/trytond/tests/test_field_numeric.py index e4743876ad..3eae64a017 100644 --- a/trytond/trytond/tests/test_field_numeric.py +++ b/trytond/trytond/tests/test_field_numeric.py @@ -461,6 +461,28 @@ class FieldNumericTestCase(unittest.TestCase): self.assertEqual(numerics, [numeric1]) + @with_transaction() + def test_search_order(self): + "Test search order" + pool = Pool() + Numeric = pool.get('test.numeric') + + Numeric.create([{ + 'numeric': Decimal('10.00'), + }, { + 'numeric': Decimal('7.00'), + }]) + + records_asc = Numeric.search([], order=[('numeric', 'ASC')]) + records_desc = Numeric.search([], order=[('numeric', 'DESC')]) + + self.assertEqual( + [r.numeric for r in records_asc], + [Decimal('7.00'), Decimal('10.00')]) + self.assertEqual( + [r.numeric for r in records_desc], + [Decimal('10.00'), Decimal('7.00')]) + @with_transaction() def test_write(self): "Test write numeric"