From ff8e6bd97119aa064d3fdabe92ea448e0b34554b Mon Sep 17 00:00:00 2001 From: Doug Lovett Date: Fri, 12 Jul 2024 07:38:35 -0700 Subject: [PATCH] Note report effective time, BCA timestamps no tz. (#1977) * Note report effective time, BCA timestamps no tz. Signed-off-by: Doug Lovett * BCA timestamps no tz. Signed-off-by: Doug Lovett --------- Signed-off-by: Doug Lovett --- mhr_api/report-templates/unitNoteV2.html | 4 +-- mhr_api/src/mhr_api/models/batch_utils.py | 11 ++++++-- mhr_api/src/mhr_api/models/utils.py | 10 ++++++++ mhr_api/src/mhr_api/reports/v2/report.py | 2 +- mhr_api/src/mhr_api/version.py | 2 +- mhr_api/tests/unit/models/test_batch_utils.py | 2 ++ mhr_api/tests/unit/models/test_utils.py | 25 +++++++++++++++++++ 7 files changed, 50 insertions(+), 6 deletions(-) diff --git a/mhr_api/report-templates/unitNoteV2.html b/mhr_api/report-templates/unitNoteV2.html index b1fdbed2c..1d2d2ee12 100644 --- a/mhr_api/report-templates/unitNoteV2.html +++ b/mhr_api/report-templates/unitNoteV2.html @@ -31,9 +31,9 @@ {% if note is defined and note.documentType is defined and note.documentType in ('NCAN', 'NRED') %} - Cancelled Date: + Cancelled Date and Time: {% else %} - Effective Date: + Effective Date and Time: {% endif %} diff --git a/mhr_api/src/mhr_api/models/batch_utils.py b/mhr_api/src/mhr_api/models/batch_utils.py index 99ab05d25..31b57aad0 100644 --- a/mhr_api/src/mhr_api/models/batch_utils.py +++ b/mhr_api/src/mhr_api/models/batch_utils.py @@ -430,8 +430,8 @@ def get_batch_registration_data(start_ts: str = None, end_ts: str = None): query = text(query_s) result = None if start_ts and end_ts: - start: str = start_ts[:19].replace('T', ' ') - end: str = end_ts[:19].replace('T', ' ') + start: str = get_query_ts(start_ts) + end: str = get_query_ts(end_ts) current_app.logger.debug(f'start={start} end={end}') result = db.session.execute(query, {'query_val1': start, 'query_val2': end}) else: @@ -445,3 +445,10 @@ def get_batch_registration_data(start_ts: str = None, end_ts: str = None): else: current_app.logger.debug('No batch registrations found within the timestamp range.') return results_json + + +def get_query_ts(request_ts: str): + """Get a query timestamp as UTC in the DB format.""" + ts = model_utils.ts_from_iso_format_no_tz(request_ts) + query_ts: str = model_utils.format_ts(ts) + return query_ts[:19].replace('T', ' ') diff --git a/mhr_api/src/mhr_api/models/utils.py b/mhr_api/src/mhr_api/models/utils.py index 157448071..7dea2fcef 100755 --- a/mhr_api/src/mhr_api/models/utils.py +++ b/mhr_api/src/mhr_api/models/utils.py @@ -294,6 +294,16 @@ def now_ts_offset(offset_days: int = 1, add: bool = False): return now - timedelta(days=offset_days) +def ts_from_iso_format_no_tz(timestamp_iso: str): + """Create a datetime object from a timestamp string in the ISO format using the local time zone.""" + if len(timestamp_iso) > 19: + return ts_from_iso_format(timestamp_iso) + ts: _datetime = _datetime.fromisoformat(timestamp_iso) + local_ts = LOCAL_TZ.localize(ts, is_dst=True) + # Return as UTC + return local_ts.astimezone(timezone.utc) + + def today_ts_offset(offset_days: int = 1, add: bool = False): """Create a timestamp representing the current date at 00:00:00 adjusted by offset number of days.""" today = date.today() diff --git a/mhr_api/src/mhr_api/reports/v2/report.py b/mhr_api/src/mhr_api/reports/v2/report.py index b7674f3dd..9dd84f442 100755 --- a/mhr_api/src/mhr_api/reports/v2/report.py +++ b/mhr_api/src/mhr_api/reports/v2/report.py @@ -548,7 +548,7 @@ def _set_note(self): elif note.get('expiryDateTime'): note['expiryDateTime'] = Report._to_report_datetime(note.get('expiryDateTime'), False) if note.get('effectiveDateTime'): - note['effectiveDateTime'] = Report._to_report_datetime(note.get('effectiveDateTime'), False) + note['effectiveDateTime'] = Report._to_report_datetime(note.get('effectiveDateTime'), True) if note.get('cancelledDateTime'): note['cancelledDateTime'] = Report._to_report_datetime(note.get('cancelledDateTime'), True) if note.get('givingNoticeParty') and note['givingNoticeParty'].get('phoneNumber'): diff --git a/mhr_api/src/mhr_api/version.py b/mhr_api/src/mhr_api/version.py index 49647dd28..ae17118e6 100644 --- a/mhr_api/src/mhr_api/version.py +++ b/mhr_api/src/mhr_api/version.py @@ -22,4 +22,4 @@ Development release segment: .devN """ -__version__ = '1.8.16' # pylint: disable=invalid-name +__version__ = '1.8.17' # pylint: disable=invalid-name diff --git a/mhr_api/tests/unit/models/test_batch_utils.py b/mhr_api/tests/unit/models/test_batch_utils.py index 4128433c9..7075daa40 100644 --- a/mhr_api/tests/unit/models/test_batch_utils.py +++ b/mhr_api/tests/unit/models/test_batch_utils.py @@ -45,6 +45,8 @@ # testdata pattern is ({start_ts}, {end_ts}) TEST_DATA_BATCH_REGISTRATION = [ ('2023-12-15T08:01:00+00:00', '2023-12-22T08:01:00+00:00'), + ('2023-12-15T00:01:00-08:00', '2023-12-22T00:01:00-00:00'), + ('2023-12-15T00:01:00', '2023-12-22T00:01:00'), (None, None) ] diff --git a/mhr_api/tests/unit/models/test_utils.py b/mhr_api/tests/unit/models/test_utils.py index f4ac5adb1..35dcf1363 100644 --- a/mhr_api/tests/unit/models/test_utils.py +++ b/mhr_api/tests/unit/models/test_utils.py @@ -21,6 +21,7 @@ from mhr_api.models import utils as model_utils from mhr_api.models.db2.search_utils import get_search_serial_number_key + DB2_IND_NAME_MIDDLE = 'DANYLUK LEONARD MICHAEL ' DB2_IND_NAME = 'KING MARDI ' DB2_IND_NAME_MAX = 'M.BELLERIVE-MAXIMILLIAN-JCHARLES-OLIVIERGUILLAUME-JEAN-CLAUDE-VAN-DAMN' @@ -80,6 +81,15 @@ (False, '2022-09-01T07:01:00+00:00', '2021-09-01T07:01:00+00:00'), (False, '2022-09-01T07:01:00+00:00', None) ] +# testdata pattern is ({test_ts}, {expected_ts}) +TEST_DATA_TS_NO_TZ = [ + ('2024-06-01T08:00:00', '2024-06-01T15:00:00+00:00'), + ('2024-09-01T21:00:00', '2024-09-02T04:00:00+00:00'), + ('2024-12-01T21:00:00', '2024-12-02T05:00:00+00:00'), + ('2024-06-01T08:00:00-07:00', '2024-06-01T15:00:00+00:00'), + ('2024-09-01T21:00:00-07:00', '2024-09-02T04:00:00+00:00'), + ('2024-12-01T21:00:00-08:00', '2024-12-02T05:00:00+00:00') +] @pytest.mark.parametrize('last, first, middle, db2_name', TEST_DATA_LEGACY_NAME) @@ -133,5 +143,20 @@ def test_tax_cert_date(session, valid, registration_ts, tax_cert_ts): def test_permit_expiry_days(session): """Assert that setting and computing expiry days works as expected.""" expiry_ts = model_utils.compute_permit_expiry() + current_app.logger.debug(model_utils.format_ts(model_utils.now_ts())) + current_app.logger.debug(model_utils.format_ts(expiry_ts)) expiry_days = model_utils.expiry_ts_days(expiry_ts) assert expiry_days == 30 + + +@pytest.mark.parametrize('registration_ts,expected_ts', TEST_DATA_TS_NO_TZ) +def test_ts_from_iso_format_no_tz(session, registration_ts, expected_ts): + """Assert that converting an ISO timestamp with no time zone works as expected.""" + reg_ts = model_utils.ts_from_iso_format_no_tz(registration_ts) + test_ts = model_utils.format_ts(reg_ts) + current_app.logger.debug(f'In={registration_ts} out={test_ts}') + assert test_ts == expected_ts + if len(registration_ts) > 19: + reg_ts = model_utils.ts_from_iso_format(registration_ts) + test_ts = model_utils.format_ts(reg_ts) + assert test_ts == expected_ts