From 34623a73072b19170918d8743bba260d30e00ea9 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Fri, 12 Feb 2021 14:05:44 -0600 Subject: [PATCH] Add special "equal to any of" verb for UPC-related grid filters --- tailbone/grids/filters.py | 45 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/tailbone/grids/filters.py b/tailbone/grids/filters.py index a8914b79..df594839 100644 --- a/tailbone/grids/filters.py +++ b/tailbone/grids/filters.py @@ -130,6 +130,7 @@ class GridFilter(object): 'is_any': "is any", 'equal': "equal to", 'not_equal': "not equal to", + 'equal_any_of': "equal to any of", 'greater_than': "greater than", 'greater_equal': "greater than or equal to", 'less_than': "less than", @@ -164,6 +165,7 @@ class GridFilter(object): ] multiple_value_verbs = [ + 'equal_any_of', 'contains_any_of', ] @@ -919,7 +921,7 @@ class AlchemyGPCFilter(AlchemyGridFilter): """ GPC filter for SQLAlchemy. """ - default_verbs = ['equal', 'not_equal'] + default_verbs = ['equal', 'not_equal', 'equal_any_of'] def filter_equal(self, query, value): """ @@ -961,6 +963,47 @@ class AlchemyGPCFilter(AlchemyGridFilter): except ValueError: return query + def filter_equal_any_of(self, query, value): + """ + This filter expects "multiple values" separated by newline character, + and will add an "OR" condition with each value being checked via + "ILIKE". For instance if the user submits a "value" like this: + + .. code-block:: none + + 07430500132 + 07430500116 + + This will result in SQL condition like this: + + .. code-block:: sql + + (upc IN (7430500132, 74305001321)) OR (upc IN (7430500116, 74305001161)) + """ + if not value: + return query + + values = value.split('\n') + values = [value for value in values if value] + if not values: + return query + + conditions = [] + for value in values: + try: + clause = self.column.in_(( + GPC(value), + GPC(value, calc_check_digit='upc'))) + except ValueError: + pass + else: + conditions.append(clause) + + if not conditions: + return query + + return query.filter(sa.or_(*conditions)) + class AlchemyPhoneNumberFilter(AlchemyStringFilter): """