Improve auto-handling of "local" timestamps

for non-Rattail DBs where timestamps are local instead of UTC
This commit is contained in:
Lance Edgar 2020-09-02 11:30:02 -05:00
parent d2d632092b
commit 72177e8ab5
3 changed files with 27 additions and 5 deletions

View file

@ -340,7 +340,8 @@ class Form(object):
auto_disable_cancel = True auto_disable_cancel = True
def __init__(self, fields=None, schema=None, request=None, mobile=False, readonly=False, readonly_fields=[], def __init__(self, fields=None, schema=None, request=None, mobile=False, readonly=False, readonly_fields=[],
model_instance=None, model_class=None, appstruct=UNSPECIFIED, nodes={}, enums={}, labels={}, renderers=None, model_instance=None, model_class=None, appstruct=UNSPECIFIED, nodes={}, enums={}, labels={},
assume_local_times=False, renderers=None,
hidden={}, widgets={}, defaults={}, validators={}, required={}, helptext={}, focus_spec=None, hidden={}, widgets={}, defaults={}, validators={}, required={}, helptext={}, focus_spec=None,
action_url=None, cancel_url=None, use_buefy=None, component='tailbone-form'): action_url=None, cancel_url=None, use_buefy=None, component='tailbone-form'):
@ -364,6 +365,7 @@ class Form(object):
self.nodes = nodes or {} self.nodes = nodes or {}
self.enums = enums or {} self.enums = enums or {}
self.labels = labels or {} self.labels = labels or {}
self.assume_local_times = assume_local_times
if renderers is None and self.model_class: if renderers is None and self.model_class:
self.renderers = self.make_renderers() self.renderers = self.make_renderers()
else: else:
@ -430,7 +432,10 @@ class Form(object):
if len(prop.columns) == 1: if len(prop.columns) == 1:
column = prop.columns[0] column = prop.columns[0]
if isinstance(column.type, sa.DateTime): if isinstance(column.type, sa.DateTime):
renderers[prop.key] = self.render_datetime if self.assume_local_times:
renderers[prop.key] = self.render_datetime_local
else:
renderers[prop.key] = self.render_datetime
elif isinstance(column.type, sa.Boolean): elif isinstance(column.type, sa.Boolean):
renderers[prop.key] = self.render_boolean renderers[prop.key] = self.render_boolean

View file

@ -2,7 +2,7 @@
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
# Copyright © 2010-2019 Lance Edgar # Copyright © 2010-2020 Lance Edgar
# #
# This file is part of Rattail. # This file is part of Rattail.
# #
@ -69,7 +69,8 @@ class Grid(object):
def __init__(self, key, data, columns=None, width='auto', request=None, mobile=False, def __init__(self, key, data, columns=None, width='auto', request=None, mobile=False,
model_class=None, model_title=None, model_title_plural=None, model_class=None, model_title=None, model_title_plural=None,
enums={}, labels={}, renderers={}, extra_row_class=None, linked_columns=[], url='#', enums={}, labels={}, assume_local_times=False, renderers={},
extra_row_class=None, linked_columns=[], url='#',
joiners={}, filterable=False, filters={}, use_byte_string_filters=False, joiners={}, filterable=False, filters={}, use_byte_string_filters=False,
sortable=False, sorters={}, default_sortkey=None, default_sortdir='asc', sortable=False, sorters={}, default_sortkey=None, default_sortdir='asc',
pageable=False, default_pagesize=20, default_page=1, pageable=False, default_pagesize=20, default_page=1,
@ -102,6 +103,7 @@ class Grid(object):
self.enums = enums or {} self.enums = enums or {}
self.labels = labels or {} self.labels = labels or {}
self.assume_local_times = assume_local_times
self.renderers = self.make_default_renderers(renderers or {}) self.renderers = self.make_default_renderers(renderers or {})
self.extra_row_class = extra_row_class self.extra_row_class = extra_row_class
self.linked_columns = linked_columns or [] self.linked_columns = linked_columns or []
@ -407,7 +409,10 @@ class Grid(object):
return self.render_boolean return self.render_boolean
if isinstance(coltype, sa.DateTime): if isinstance(coltype, sa.DateTime):
return self.render_datetime if self.assume_local_times:
return self.render_datetime_local
else:
return self.render_datetime
if isinstance(coltype, GPCType): if isinstance(coltype, GPCType):
return self.render_gpc return self.render_gpc

View file

@ -424,6 +424,7 @@ class MasterView(View):
'url': lambda obj: self.get_action_url('view', obj), 'url': lambda obj: self.get_action_url('view', obj),
'checkboxes': checkboxes, 'checkboxes': checkboxes,
'checked': self.checked, 'checked': self.checked,
'assume_local_times': self.has_local_times,
} }
if 'main_actions' not in kwargs and 'more_actions' not in kwargs: if 'main_actions' not in kwargs and 'more_actions' not in kwargs:
main, more = self.get_grid_actions() main, more = self.get_grid_actions()
@ -2961,6 +2962,16 @@ class MasterView(View):
Coerce the given data dict record, to a "row" dict suitable for use Coerce the given data dict record, to a "row" dict suitable for use
when writing directly to XLSX file. when writing directly to XLSX file.
""" """
data = dict(data)
for key in data:
value = data[key]
# make timestamps local, "zone-naive"
if isinstance(value, datetime.datetime):
value = localtime(self.rattail_config, value, tzinfo=False)
data[key] = value
return data return data
def results_csv(self): def results_csv(self):
@ -3504,6 +3515,7 @@ class MasterView(View):
'model_class': getattr(self, 'model_class', None), 'model_class': getattr(self, 'model_class', None),
'action_url': self.request.current_route_url(_query=None), 'action_url': self.request.current_route_url(_query=None),
'use_buefy': self.get_use_buefy(), 'use_buefy': self.get_use_buefy(),
'assume_local_times': self.has_local_times,
} }
if self.creating: if self.creating:
kwargs.setdefault('cancel_url', self.get_index_url()) kwargs.setdefault('cancel_url', self.get_index_url())