From fd18256efbca20a3343e4e2ff5360db41c7290a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 31 May 2022 23:46:14 +0200 Subject: [PATCH] Invert SQL expression of domain_active When the value is False or the operator is negative, the range expression must be inverted. issue11492 review419171003 --- common.py | 31 +++++++++++++++---------------- tests/scenario_account_active.rst | 13 +++++++++++++ 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/common.py b/common.py index bde4103e70..cd5da5ff2a 100644 --- a/common.py +++ b/common.py @@ -121,25 +121,24 @@ class ActivePeriodMixin(PeriodMixin): table, _ = tables[None] _, operator, value = domain - if operator in {'=', '!='}: - if (operator == '=') == value: - operator = 'in' - else: - operator = 'not in' - elif operator in {'in', 'not in'}: - if True in value and False not in value: - operator = 'in' - elif False in value and True not in value: - operator = 'not in' - else: - return Literal(True) - else: - return Literal(True) - from_date, to_date = cls._active_dates() start_date = Coalesce(table.start_date, datetime.date.min) end_date = Coalesce(table.end_date, datetime.date.max) - return (((start_date <= to_date) & (end_date >= to_date)) + expression = (((start_date <= to_date) & (end_date >= to_date)) | ((start_date <= from_date) & (end_date >= from_date)) | ((start_date >= from_date) & (end_date <= to_date))) + + if operator in {'=', '!='}: + if (operator == '=') != value: + expression = ~expression + elif operator in {'in', 'not in'}: + if True in value and False not in value: + pass + elif False in value and True not in value: + expression = ~expression + else: + expression = Literal(True) + else: + expression = Literal(True) + return expression diff --git a/tests/scenario_account_active.rst b/tests/scenario_account_active.rst index 40e1480dfd..058c1245f1 100644 --- a/tests/scenario_account_active.rst +++ b/tests/scenario_account_active.rst @@ -41,6 +41,19 @@ Check active without start or end date:: True >>> len(Account.find([('id', '=', cash.id)])) 1 + >>> len(Account.find([('id', '=', cash.id), ('active', '=', True)])) + 1 + >>> len(Account.find([('id', '=', cash.id), ('active', 'in', [True])])) + 1 + >>> len(Account.find([('id', '=', cash.id), ('active', 'in', [True, False])])) + 1 + +Check negative search:: + + >>> len(Account.find([('id', '=', cash.id), ('active', '=', False)])) + 0 + >>> len(Account.find([('id', '=', cash.id), ('active', 'in', [False])])) + 0 Check active with a start date::