From 72177e8ab567a1739cbf87e3b5a32d01978a19cb Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Wed, 2 Sep 2020 11:30:02 -0500 Subject: [PATCH] Improve auto-handling of "local" timestamps for non-Rattail DBs where timestamps are local instead of UTC --- tailbone/forms/core.py | 9 +++++++-- tailbone/grids/core.py | 11 ++++++++--- tailbone/views/master.py | 12 ++++++++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/tailbone/forms/core.py b/tailbone/forms/core.py index cf7dd49e..7441e4ab 100644 --- a/tailbone/forms/core.py +++ b/tailbone/forms/core.py @@ -340,7 +340,8 @@ class Form(object): auto_disable_cancel = True 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, action_url=None, cancel_url=None, use_buefy=None, component='tailbone-form'): @@ -364,6 +365,7 @@ class Form(object): self.nodes = nodes or {} self.enums = enums or {} self.labels = labels or {} + self.assume_local_times = assume_local_times if renderers is None and self.model_class: self.renderers = self.make_renderers() else: @@ -430,7 +432,10 @@ class Form(object): if len(prop.columns) == 1: column = prop.columns[0] 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): renderers[prop.key] = self.render_boolean diff --git a/tailbone/grids/core.py b/tailbone/grids/core.py index d475370c..442568de 100644 --- a/tailbone/grids/core.py +++ b/tailbone/grids/core.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2019 Lance Edgar +# Copyright © 2010-2020 Lance Edgar # # 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, 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, sortable=False, sorters={}, default_sortkey=None, default_sortdir='asc', pageable=False, default_pagesize=20, default_page=1, @@ -102,6 +103,7 @@ class Grid(object): self.enums = enums or {} self.labels = labels or {} + self.assume_local_times = assume_local_times self.renderers = self.make_default_renderers(renderers or {}) self.extra_row_class = extra_row_class self.linked_columns = linked_columns or [] @@ -407,7 +409,10 @@ class Grid(object): return self.render_boolean 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): return self.render_gpc diff --git a/tailbone/views/master.py b/tailbone/views/master.py index c2720d6e..6b6c8305 100644 --- a/tailbone/views/master.py +++ b/tailbone/views/master.py @@ -424,6 +424,7 @@ class MasterView(View): 'url': lambda obj: self.get_action_url('view', obj), 'checkboxes': checkboxes, 'checked': self.checked, + 'assume_local_times': self.has_local_times, } if 'main_actions' not in kwargs and 'more_actions' not in kwargs: 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 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 def results_csv(self): @@ -3504,6 +3515,7 @@ class MasterView(View): 'model_class': getattr(self, 'model_class', None), 'action_url': self.request.current_route_url(_query=None), 'use_buefy': self.get_use_buefy(), + 'assume_local_times': self.has_local_times, } if self.creating: kwargs.setdefault('cancel_url', self.get_index_url())