fix: add grid filter for animal birthdate

This commit is contained in:
Lance Edgar 2026-02-20 21:37:57 -06:00
parent 5d7dea5a84
commit c976d94bdd
2 changed files with 99 additions and 10 deletions

View file

@ -23,6 +23,8 @@
Custom grid stuff for use with farmOS / JSONAPI
"""
import datetime
from wuttaweb.grids.filters import GridFilter
@ -35,12 +37,12 @@ class SimpleFilter(GridFilter):
self.path = path or key
def filter_equal(self, data, value):
if value:
if value := self.coerce_value(value):
data.add_filter(self.path, "=", value)
return data
def filter_not_equal(self, data, value):
if value:
if value := self.coerce_value(value):
data.add_filter(self.path, "<>", value)
return data
@ -58,7 +60,7 @@ class StringFilter(SimpleFilter):
default_verbs = ["contains", "equal", "not_equal"]
def filter_contains(self, data, value):
if value:
if value := self.coerce_value(value):
data.add_filter(self.path, "CONTAINS", value)
return data
@ -80,22 +82,22 @@ class IntegerFilter(SimpleFilter):
]
def filter_less_than(self, data, value):
if value:
if value := self.coerce_value(value):
data.add_filter(self.path, "<", value)
return data
def filter_less_equal(self, data, value):
if value:
if value := self.coerce_value(value):
data.add_filter(self.path, "<=", value)
return data
def filter_greater_than(self, data, value):
if value:
if value := self.coerce_value(value):
data.add_filter(self.path, ">", value)
return data
def filter_greater_equal(self, data, value):
if value:
if value := self.coerce_value(value):
data.add_filter(self.path, ">=", value)
return data
@ -123,6 +125,88 @@ class NullableBooleanFilter(BooleanFilter):
default_verbs = ["is_true", "is_false", "is_null", "is_not_null"]
# TODO: this may not work, it's not used anywhere yet
class DateFilter(SimpleFilter):
data_type = "date"
default_verbs = [
"equal",
"not_equal",
"greater_than",
"greater_equal",
"less_than",
"less_equal",
# 'between',
]
default_verb_labels = {
"equal": "on",
"not_equal": "not on",
"greater_than": "after",
"greater_equal": "on or after",
"less_than": "before",
"less_equal": "on or before",
# "between": "between",
"is_null": "is null",
"is_not_null": "is not null",
"is_any": "is any",
}
def coerce_value(self, value):
if value:
if isinstance(value, datetime.date):
return value
try:
dt = datetime.datetime.strptime(value, "%Y-%m-%d")
except ValueError:
log.warning("invalid date value: %s", value)
else:
return dt.date()
return None
# TODO: this is not very complete yet, so far used only for animal birthdate
class DateTimeFilter(DateFilter):
default_verbs = ["equal", "is_null", "is_not_null"]
def coerce_value(self, value):
"""
Convert user input to a proper ``datetime.date`` object.
"""
if value:
if isinstance(value, datetime.date):
return value
try:
dt = datetime.datetime.strptime(value, "%Y-%m-%d")
except ValueError:
log.warning("invalid date value: %s", value)
else:
return dt.date()
return None
def filter_equal(self, data, value):
if value := self.coerce_value(value):
start = datetime.datetime.combine(value, datetime.time(0))
start = self.app.localtime(start, from_utc=False)
stop = datetime.datetime.combine(
value + datetime.timedelta(days=1), datetime.time(0)
)
stop = self.app.localtime(stop, from_utc=False)
data.add_filter(self.path, ">=", int(start.timestamp()))
data.add_filter(self.path, "<", int(stop.timestamp()))
return data
class SimpleSorter:
def __init__(self, key):
@ -171,10 +255,13 @@ class ResourceData:
if self._data is None:
params = {}
i = 0
for path, operator, value in self.filters:
params[f"filter[{path}][condition][path]"] = path
params[f"filter[{path}][condition][operator]"] = operator
params[f"filter[{path}][condition][value]"] = value
i += 1
key = f"{i:03d}"
params[f"filter[{key}][condition][path]"] = path
params[f"filter[{key}][condition][operator]"] = operator
params[f"filter[{key}][condition][value]"] = value
sorters = []
for path, sortdir in self.sorters:

View file

@ -37,6 +37,7 @@ from wuttafarm.web.grids import (
StringFilter,
BooleanFilter,
NullableBooleanFilter,
DateTimeFilter,
)
from wuttafarm.web.forms.schema import AnimalTypeType
@ -120,6 +121,7 @@ class AnimalView(AssetMasterView):
# birthdate
g.set_renderer("birthdate", "date")
g.set_sorter("birthdate", SimpleSorter("birthdate"))
g.set_filter("birthdate", DateTimeFilter)
# sex
g.set_enum("sex", enum.ANIMAL_SEX)