diff --git a/app/celery/tasks.py b/app/celery/tasks.py index dc69427a5..92af2bdac 100644 --- a/app/celery/tasks.py +++ b/app/celery/tasks.py @@ -11,6 +11,7 @@ from notifications_utils.template import ( SMSMessageTemplate, WithSubjectTemplate, ) +from notifications_utils.timezones import convert_utc_to_bst from requests import ( HTTPError, request, @@ -72,7 +73,6 @@ from app.models import ( ) from app.notifications.process_notifications import persist_notification from app.service.utils import service_allowed_to_send_to -from app.utils import convert_utc_to_bst @notify_celery.task(name="process-job") diff --git a/app/clients/performance_platform/performance_platform_client.py b/app/clients/performance_platform/performance_platform_client.py index d04b22659..66cecb4c0 100644 --- a/app/clients/performance_platform/performance_platform_client.py +++ b/app/clients/performance_platform/performance_platform_client.py @@ -4,7 +4,7 @@ import json from flask import current_app import requests -from app.utils import convert_utc_to_bst +from notifications_utils.timezones import convert_utc_to_bst class PerformancePlatformClient: diff --git a/app/config.py b/app/config.py index b5bcbb42b..1ba7d6edc 100644 --- a/app/config.py +++ b/app/config.py @@ -1,4 +1,4 @@ -from datetime import timedelta, time +from datetime import timedelta import os import json @@ -318,8 +318,6 @@ class Config(object): DOCUMENT_DOWNLOAD_API_HOST = os.environ.get('DOCUMENT_DOWNLOAD_API_HOST', 'http://localhost:7000') DOCUMENT_DOWNLOAD_API_KEY = os.environ.get('DOCUMENT_DOWNLOAD_API_KEY', 'auth-token') - LETTER_PROCESSING_DEADLINE = time(17, 30) - MMG_URL = "https://api.mmg.co.uk/json/api.php" AWS_REGION = 'eu-west-1' diff --git a/app/dao/date_util.py b/app/dao/date_util.py index 1e93e845f..f9533a826 100644 --- a/app/dao/date_util.py +++ b/app/dao/date_util.py @@ -1,9 +1,8 @@ from datetime import datetime, timedelta +from notifications_utils.timezones import convert_bst_to_utc import pytz -from app.utils import convert_bst_to_utc - def get_months_for_financial_year(year): return [ diff --git a/app/dao/fact_billing_dao.py b/app/dao/fact_billing_dao.py index e3f7f221b..bdc2011a6 100644 --- a/app/dao/fact_billing_dao.py +++ b/app/dao/fact_billing_dao.py @@ -1,6 +1,7 @@ from datetime import datetime, timedelta, time from flask import current_app +from notifications_utils.timezones import convert_bst_to_utc, convert_utc_to_bst from sqlalchemy.dialects.postgresql import insert from sqlalchemy import func, case, desc, Date, Integer @@ -20,7 +21,6 @@ from app.models import ( EMAIL_TYPE, NOTIFICATION_STATUS_TYPES_BILLABLE_FOR_LETTERS ) -from app.utils import convert_utc_to_bst, convert_bst_to_utc def fetch_billing_totals_for_year(service_id, year): diff --git a/app/dao/fact_notification_status_dao.py b/app/dao/fact_notification_status_dao.py index 566d5f40e..f80f175d8 100644 --- a/app/dao/fact_notification_status_dao.py +++ b/app/dao/fact_notification_status_dao.py @@ -1,6 +1,7 @@ from datetime import datetime, timedelta, time from flask import current_app +from notifications_utils.timezones import convert_bst_to_utc from sqlalchemy import func from sqlalchemy.dialects.postgresql import insert from sqlalchemy.sql.expression import literal @@ -8,7 +9,7 @@ from sqlalchemy.types import DateTime, Integer from app import db from app.models import Notification, NotificationHistory, FactNotificationStatus, KEY_TYPE_TEST -from app.utils import convert_bst_to_utc, get_london_midnight_in_utc, midnight_n_days_ago +from app.utils import get_london_midnight_in_utc, midnight_n_days_ago def fetch_notification_status_for_day(process_day, service_id=None): diff --git a/app/dao/notifications_dao.py b/app/dao/notifications_dao.py index f170c2410..564ab6acf 100644 --- a/app/dao/notifications_dao.py +++ b/app/dao/notifications_dao.py @@ -20,6 +20,7 @@ from sqlalchemy.orm import joinedload from sqlalchemy.sql.expression import case from sqlalchemy.sql import functions from notifications_utils.international_billing_rates import INTERNATIONAL_BILLING_RATES +from notifications_utils.timezones import convert_utc_to_bst from app import db, create_uuid from app.aws.s3 import remove_s3_object, get_s3_bucket_objects @@ -48,7 +49,7 @@ from app.models import ( ) from app.dao.dao_utils import transactional -from app.utils import convert_utc_to_bst, get_london_midnight_in_utc +from app.utils import get_london_midnight_in_utc @statsd(namespace="dao") diff --git a/app/letters/utils.py b/app/letters/utils.py index fc84b50ac..03cd573f9 100644 --- a/app/letters/utils.py +++ b/app/letters/utils.py @@ -4,10 +4,11 @@ from enum import Enum import boto3 from flask import current_app +from notifications_utils.letter_timings import LETTER_PROCESSING_DEADLINE from notifications_utils.s3 import s3upload +from notifications_utils.timezones import convert_utc_to_bst from app.models import KEY_TYPE_TEST, SECOND_CLASS, RESOLVE_POSTAGE_FOR_FILE_NAME, NOTIFICATION_VALIDATION_FAILED -from app.utils import convert_utc_to_bst class ScanErrorType(Enum): @@ -26,7 +27,7 @@ def get_folder_name(_now, is_test_or_scan_letter=False): folder_name = '' else: print_datetime = convert_utc_to_bst(_now) - if print_datetime.time() > current_app.config.get('LETTER_PROCESSING_DEADLINE'): + if print_datetime.time() > LETTER_PROCESSING_DEADLINE: print_datetime += timedelta(days=1) folder_name = '{}/'.format(print_datetime.date()) return folder_name diff --git a/app/models.py b/app/models.py index 8cb2e6ede..e2d86679a 100644 --- a/app/models.py +++ b/app/models.py @@ -26,6 +26,7 @@ from notifications_utils.template import ( SMSMessageTemplate, LetterPrintTemplate, ) +from notifications_utils.timezones import convert_bst_to_utc, convert_utc_to_bst from app.encryption import ( hashpw, @@ -38,7 +39,6 @@ from app import ( ) from app.history_meta import Versioned -from app.utils import convert_utc_to_bst, convert_bst_to_utc SMS_TYPE = 'sms' EMAIL_TYPE = 'email' diff --git a/app/notifications/process_notifications.py b/app/notifications/process_notifications.py index 46b78941d..6483ac766 100644 --- a/app/notifications/process_notifications.py +++ b/app/notifications/process_notifications.py @@ -9,6 +9,7 @@ from notifications_utils.recipients import ( validate_and_format_phone_number, format_email_address ) +from notifications_utils.timezones import convert_bst_to_utc, convert_utc_to_bst from app import redis_store from app.celery import provider_tasks @@ -34,8 +35,6 @@ from app.v2.errors import BadRequestError from app.utils import ( cache_key_for_service_template_counter, cache_key_for_service_template_usage_per_day, - convert_bst_to_utc, - convert_utc_to_bst, get_template_instance, ) diff --git a/app/notifications/receive_notifications.py b/app/notifications/receive_notifications.py index b73730ece..848c7d239 100644 --- a/app/notifications/receive_notifications.py +++ b/app/notifications/receive_notifications.py @@ -3,6 +3,7 @@ from urllib.parse import unquote import iso8601 from flask import jsonify, Blueprint, current_app, request, abort from notifications_utils.recipients import try_validate_and_format_phone_number +from notifications_utils.timezones import convert_bst_to_utc from app import statsd_client from app.celery import tasks @@ -11,7 +12,6 @@ from app.dao.services_dao import dao_fetch_service_by_inbound_number from app.dao.inbound_sms_dao import dao_create_inbound_sms from app.models import InboundSms, INBOUND_SMS_TYPE, SMS_TYPE from app.errors import register_errors -from app.utils import convert_bst_to_utc receive_notifications_blueprint = Blueprint('receive_notifications', __name__) register_errors(receive_notifications_blueprint) diff --git a/app/service/statistics.py b/app/service/statistics.py index 10bff90b3..3d22b20d6 100644 --- a/app/service/statistics.py +++ b/app/service/statistics.py @@ -1,8 +1,9 @@ from collections import defaultdict from datetime import datetime +from notifications_utils.timezones import convert_utc_to_bst + from app.models import NOTIFICATION_STATUS_TYPES, TEMPLATE_TYPES -from app.utils import convert_utc_to_bst from app.dao.date_util import get_months_for_financial_year diff --git a/app/utils.py b/app/utils.py index 9dacd616c..b00a53bda 100644 --- a/app/utils.py +++ b/app/utils.py @@ -4,6 +4,7 @@ import pytz from flask import url_for from sqlalchemy import func from notifications_utils.template import SMSMessageTemplate, WithSubjectTemplate +from notifications_utils.timezones import convert_utc_to_bst local_timezone = pytz.timezone("Europe/London") @@ -51,14 +52,6 @@ def get_midnight_for_day_before(date): return get_london_midnight_in_utc(day_before) -def convert_utc_to_bst(utc_dt): - return pytz.utc.localize(utc_dt).astimezone(local_timezone).replace(tzinfo=None) - - -def convert_bst_to_utc(date): - return local_timezone.localize(date).astimezone(pytz.UTC).replace(tzinfo=None) - - def get_london_month_from_utc_column(column): """ Where queries need to count notifications by month it needs to be diff --git a/requirements-app.txt b/requirements-app.txt index e9e2e4674..8e1812f49 100644 --- a/requirements-app.txt +++ b/requirements-app.txt @@ -29,6 +29,6 @@ awscli-cwlogs>=1.4,<1.5 # Putting upgrade on hold due to v1.0.0 using sha512 instead of sha1 by default itsdangerous==0.24 # pyup: <1.0.0 -git+https://github.com/alphagov/notifications-utils.git@30.5.6#egg=notifications-utils==30.5.6 +git+https://github.com/alphagov/notifications-utils.git@30.7.0#egg=notifications-utils==30.7.0 git+https://github.com/alphagov/boto.git@2.43.0-patch3#egg=boto==2.43.0-patch3 diff --git a/requirements.txt b/requirements.txt index d80c5f3e3..a21b7c1ff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,21 +31,21 @@ awscli-cwlogs>=1.4,<1.5 # Putting upgrade on hold due to v1.0.0 using sha512 instead of sha1 by default itsdangerous==0.24 # pyup: <1.0.0 -git+https://github.com/alphagov/notifications-utils.git@30.5.6#egg=notifications-utils==30.5.6 +git+https://github.com/alphagov/notifications-utils.git@30.7.0#egg=notifications-utils==30.7.0 git+https://github.com/alphagov/boto.git@2.43.0-patch3#egg=boto==2.43.0-patch3 ## The following requirements were added by pip freeze: -alembic==1.0.2 +alembic==1.0.3 amqp==1.4.9 anyjson==0.3.3 attrs==18.2.0 -awscli==1.16.53 +awscli==1.16.61 bcrypt==3.1.4 billiard==3.3.0.23 bleach==2.1.3 boto3==1.6.16 -botocore==1.12.43 +botocore==1.12.51 certifi==2018.10.15 chardet==3.0.4 Click==7.0 @@ -68,7 +68,7 @@ phonenumbers==8.9.4 pyasn1==0.4.4 pycparser==2.19 PyPDF2==1.26.0 -pyrsistent==0.14.5 +pyrsistent==0.14.7 python-dateutil==2.7.5 python-editor==1.0.3 python-json-logger==0.1.8 diff --git a/requirements_for_test.txt b/requirements_for_test.txt index d286b3400..824f9482d 100644 --- a/requirements_for_test.txt +++ b/requirements_for_test.txt @@ -1,6 +1,6 @@ -r requirements.txt flake8==3.6.0 -pytest==3.10.0 +pytest==3.10.1 moto==1.3.7 pytest-env==0.6.2 pytest-mock==1.10.0 diff --git a/tests/app/dao/test_ft_billing_dao.py b/tests/app/dao/test_ft_billing_dao.py index 213fed7a9..f36e02180 100644 --- a/tests/app/dao/test_ft_billing_dao.py +++ b/tests/app/dao/test_ft_billing_dao.py @@ -6,6 +6,8 @@ from freezegun import freeze_time import pytest +from notifications_utils.timezones import convert_utc_to_bst + from app import db from app.dao.fact_billing_dao import ( delete_billing_data_for_service_for_day, @@ -20,7 +22,6 @@ from app.models import ( Notification, NOTIFICATION_STATUS_TYPES, ) -from app.utils import convert_utc_to_bst from tests.app.db import ( create_ft_billing, create_service, diff --git a/tests/app/test_utils.py b/tests/app/test_utils.py index d6488946d..8f105b588 100644 --- a/tests/app/test_utils.py +++ b/tests/app/test_utils.py @@ -6,8 +6,6 @@ from freezegun import freeze_time from app.utils import ( get_london_midnight_in_utc, get_midnight_for_day_before, - convert_utc_to_bst, - convert_bst_to_utc, midnight_n_days_ago, last_n_days ) @@ -31,26 +29,6 @@ def test_get_midnight_for_day_before_returns_expected_date(date, expected_date): assert get_midnight_for_day_before(date) == expected_date -@pytest.mark.parametrize('date, expected_date', [ - (datetime(2017, 3, 26, 23, 0), datetime(2017, 3, 27, 0, 0)), # 2017 BST switchover - (datetime(2017, 3, 20, 23, 0), datetime(2017, 3, 20, 23, 0)), - (datetime(2017, 3, 28, 10, 0), datetime(2017, 3, 28, 11, 0)), - (datetime(2017, 10, 28, 1, 0), datetime(2017, 10, 28, 2, 0)), - (datetime(2017, 10, 29, 1, 0), datetime(2017, 10, 29, 1, 0)), - (datetime(2017, 5, 12, 14), datetime(2017, 5, 12, 15, 0)) -]) -def test_get_utc_in_bst_returns_expected_date(date, expected_date): - ret_date = convert_utc_to_bst(date) - assert ret_date == expected_date - - -def test_convert_bst_to_utc(): - bst = "2017-05-12 13:15" - bst_datetime = datetime.strptime(bst, "%Y-%m-%d %H:%M") - utc = convert_bst_to_utc(bst_datetime) - assert utc == datetime(2017, 5, 12, 12, 15) - - @pytest.mark.parametrize('current_time, arg, expected_datetime', [ # winter ('2018-01-10 23:59', 1, datetime(2018, 1, 9, 0, 0)),