mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-01 07:35:34 -05:00
Merge pull request #824 from alphagov/feat-switch-providers-on-slow-delivery
Auto-switch providers on slow delivery of notifications
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import pytest
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from functools import partial
|
||||
|
||||
@@ -13,19 +15,57 @@ from app.celery.scheduled_tasks import (
|
||||
delete_invitations,
|
||||
timeout_notifications,
|
||||
run_scheduled_jobs,
|
||||
send_daily_performance_platform_stats
|
||||
send_daily_performance_platform_stats,
|
||||
switch_current_sms_provider_on_slow_delivery
|
||||
)
|
||||
from app.clients.performance_platform.performance_platform_client import PerformancePlatformClient
|
||||
from app.dao.jobs_dao import dao_get_job_by_id
|
||||
from app.dao.provider_details_dao import (
|
||||
dao_update_provider_details,
|
||||
get_current_provider
|
||||
)
|
||||
from app.models import Service, Template
|
||||
from app.utils import get_london_midnight_in_utc
|
||||
from tests.app.db import create_notification, create_service, create_template
|
||||
from tests.app.conftest import (
|
||||
sample_notification as create_sample_notification,
|
||||
sample_job as create_sample_job,
|
||||
sample_notification_history as create_notification_history
|
||||
)
|
||||
from tests.conftest import set_config_values
|
||||
from unittest.mock import call, patch, PropertyMock
|
||||
|
||||
|
||||
def _create_slow_delivery_notification(provider='mmg'):
|
||||
now = datetime.utcnow()
|
||||
five_minutes_from_now = now + timedelta(minutes=5)
|
||||
service = Service.query.get(current_app.config['FUNCTIONAL_TEST_PROVIDER_SERVICE_ID'])
|
||||
if not service:
|
||||
service = create_service(
|
||||
service_id=current_app.config.get('FUNCTIONAL_TEST_PROVIDER_SERVICE_ID')
|
||||
)
|
||||
|
||||
template = Template.query.get(current_app.config['FUNCTIONAL_TEST_PROVIDER_SMS_TEMPLATE_ID'])
|
||||
if not template:
|
||||
template = create_template(
|
||||
template_id=current_app.config.get('FUNCTIONAL_TEST_PROVIDER_SMS_TEMPLATE_ID'),
|
||||
service=service
|
||||
)
|
||||
|
||||
create_notification(
|
||||
template=template,
|
||||
status='delivered',
|
||||
sent_by=provider,
|
||||
updated_at=five_minutes_from_now
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def prepare_current_provider(restore_provider_details):
|
||||
initial_provider = get_current_provider('sms')
|
||||
initial_provider.updated_at = datetime.utcnow() - timedelta(minutes=30)
|
||||
dao_update_provider_details(initial_provider)
|
||||
|
||||
|
||||
def test_should_have_decorated_tasks_functions():
|
||||
assert delete_verify_codes.__wrapped__.__name__ == 'delete_verify_codes'
|
||||
assert delete_successful_notifications.__wrapped__.__name__ == 'delete_successful_notifications'
|
||||
@@ -35,6 +75,8 @@ def test_should_have_decorated_tasks_functions():
|
||||
assert run_scheduled_jobs.__wrapped__.__name__ == 'run_scheduled_jobs'
|
||||
assert remove_csv_files.__wrapped__.__name__ == 'remove_csv_files'
|
||||
assert send_daily_performance_platform_stats.__wrapped__.__name__ == 'send_daily_performance_platform_stats'
|
||||
assert switch_current_sms_provider_on_slow_delivery.__wrapped__.__name__ == \
|
||||
'switch_current_sms_provider_on_slow_delivery'
|
||||
|
||||
|
||||
def test_should_call_delete_successful_notifications_more_than_week_in_task(notify_api, mocker):
|
||||
@@ -68,26 +110,17 @@ def test_update_status_of_notifications_after_timeout(notify_api,
|
||||
sample_template,
|
||||
mmg_provider):
|
||||
with notify_api.test_request_context():
|
||||
not1 = create_sample_notification(
|
||||
notify_db,
|
||||
notify_db_session,
|
||||
service=sample_service,
|
||||
not1 = create_notification(
|
||||
template=sample_template,
|
||||
status='sending',
|
||||
created_at=datetime.utcnow() - timedelta(
|
||||
seconds=current_app.config.get('SENDING_NOTIFICATIONS_TIMEOUT_PERIOD') + 10))
|
||||
not2 = create_sample_notification(
|
||||
notify_db,
|
||||
notify_db_session,
|
||||
service=sample_service,
|
||||
not2 = create_notification(
|
||||
template=sample_template,
|
||||
status='created',
|
||||
created_at=datetime.utcnow() - timedelta(
|
||||
seconds=current_app.config.get('SENDING_NOTIFICATIONS_TIMEOUT_PERIOD') + 10))
|
||||
not3 = create_sample_notification(
|
||||
notify_db,
|
||||
notify_db_session,
|
||||
service=sample_service,
|
||||
not3 = create_notification(
|
||||
template=sample_template,
|
||||
status='pending',
|
||||
created_at=datetime.utcnow() - timedelta(
|
||||
@@ -105,10 +138,7 @@ def test_not_update_status_of_notification_before_timeout(notify_api,
|
||||
sample_template,
|
||||
mmg_provider):
|
||||
with notify_api.test_request_context():
|
||||
not1 = create_sample_notification(
|
||||
notify_db,
|
||||
notify_db_session,
|
||||
service=sample_service,
|
||||
not1 = create_notification(
|
||||
template=sample_template,
|
||||
status='sending',
|
||||
created_at=datetime.utcnow() - timedelta(
|
||||
@@ -244,3 +274,122 @@ def test_send_daily_performance_stats_calls_with_correct_totals(
|
||||
call(get_london_midnight_in_utc(yesterday), 'sms', 2, 'day'),
|
||||
call(get_london_midnight_in_utc(yesterday), 'email', 3, 'day')
|
||||
])
|
||||
|
||||
|
||||
def test_switch_current_sms_provider_on_slow_delivery_does_not_run_if_config_unset(
|
||||
notify_api,
|
||||
mocker
|
||||
):
|
||||
get_notifications_mock = mocker.patch(
|
||||
'app.celery.scheduled_tasks.is_delivery_slow_for_provider'
|
||||
)
|
||||
toggle_sms_mock = mocker.patch('app.celery.scheduled_tasks.dao_toggle_sms_provider')
|
||||
|
||||
with set_config_values(notify_api, {
|
||||
'FUNCTIONAL_TEST_PROVIDER_SERVICE_ID': None,
|
||||
'FUNCTIONAL_TEST_PROVIDER_SMS_TEMPLATE_ID': None
|
||||
}):
|
||||
switch_current_sms_provider_on_slow_delivery()
|
||||
|
||||
assert get_notifications_mock.called is False
|
||||
assert toggle_sms_mock.called is False
|
||||
|
||||
|
||||
def test_switch_providers_on_slow_delivery_runs_if_config_set(
|
||||
notify_api,
|
||||
mocker,
|
||||
prepare_current_provider
|
||||
):
|
||||
get_notifications_mock = mocker.patch(
|
||||
'app.celery.scheduled_tasks.is_delivery_slow_for_provider',
|
||||
return_value=[]
|
||||
)
|
||||
|
||||
with set_config_values(notify_api, {
|
||||
'FUNCTIONAL_TEST_PROVIDER_SERVICE_ID': '7954469d-8c6d-43dc-b8f7-86be2d69f5f3',
|
||||
'FUNCTIONAL_TEST_PROVIDER_SMS_TEMPLATE_ID': '331a63e6-f1aa-4588-ad3f-96c268788ae7'
|
||||
}):
|
||||
switch_current_sms_provider_on_slow_delivery()
|
||||
|
||||
assert get_notifications_mock.called is True
|
||||
|
||||
|
||||
def test_switch_providers_triggers_on_slow_notification_delivery(
|
||||
notify_api,
|
||||
prepare_current_provider
|
||||
):
|
||||
starting_provider = get_current_provider('sms')
|
||||
|
||||
with set_config_values(notify_api, {
|
||||
'FUNCTIONAL_TEST_PROVIDER_SERVICE_ID': '7954469d-8c6d-43dc-b8f7-86be2d69f5f3',
|
||||
'FUNCTIONAL_TEST_PROVIDER_SMS_TEMPLATE_ID': '331a63e6-f1aa-4588-ad3f-96c268788ae7'
|
||||
}):
|
||||
_create_slow_delivery_notification(starting_provider.identifier)
|
||||
_create_slow_delivery_notification(starting_provider.identifier)
|
||||
switch_current_sms_provider_on_slow_delivery()
|
||||
|
||||
new_provider = get_current_provider('sms')
|
||||
assert new_provider.identifier != starting_provider.identifier
|
||||
assert new_provider.priority < starting_provider.priority
|
||||
|
||||
|
||||
def test_switch_providers_on_slow_delivery_does_not_switch_if_already_switched(
|
||||
notify_api,
|
||||
prepare_current_provider
|
||||
):
|
||||
starting_provider = get_current_provider('sms')
|
||||
|
||||
with set_config_values(notify_api, {
|
||||
'FUNCTIONAL_TEST_PROVIDER_SERVICE_ID': '7954469d-8c6d-43dc-b8f7-86be2d69f5f3',
|
||||
'FUNCTIONAL_TEST_PROVIDER_SMS_TEMPLATE_ID': '331a63e6-f1aa-4588-ad3f-96c268788ae7'
|
||||
}):
|
||||
_create_slow_delivery_notification()
|
||||
_create_slow_delivery_notification()
|
||||
|
||||
switch_current_sms_provider_on_slow_delivery()
|
||||
switch_current_sms_provider_on_slow_delivery()
|
||||
|
||||
new_provider = get_current_provider('sms')
|
||||
assert new_provider.identifier != starting_provider.identifier
|
||||
assert new_provider.priority < starting_provider.priority
|
||||
|
||||
|
||||
def test_switch_providers_on_slow_delivery_does_not_switch_based_on_older_notifications(
|
||||
notify_api,
|
||||
prepare_current_provider
|
||||
):
|
||||
"""
|
||||
Assume we have three slow delivery notifications for the current provider x. This triggers
|
||||
a switch to provider y. If we experience some slow delivery notifications on this provider,
|
||||
we switch back to provider x.
|
||||
|
||||
Provider x had three slow deliveries initially, but we do not want to trigger another switch
|
||||
based on these as they are old. We only want to look for slow notifications after the point at
|
||||
which we switched back to provider x.
|
||||
"""
|
||||
starting_provider = get_current_provider('sms')
|
||||
with set_config_values(notify_api, {
|
||||
'FUNCTIONAL_TEST_PROVIDER_SERVICE_ID': '7954469d-8c6d-43dc-b8f7-86be2d69f5f3',
|
||||
'FUNCTIONAL_TEST_PROVIDER_SMS_TEMPLATE_ID': '331a63e6-f1aa-4588-ad3f-96c268788ae7'
|
||||
}):
|
||||
# Provider x -> y
|
||||
_create_slow_delivery_notification(starting_provider.identifier)
|
||||
_create_slow_delivery_notification(starting_provider.identifier)
|
||||
_create_slow_delivery_notification(starting_provider.identifier)
|
||||
switch_current_sms_provider_on_slow_delivery()
|
||||
|
||||
current_provider = get_current_provider('sms')
|
||||
assert current_provider.identifier != starting_provider.identifier
|
||||
|
||||
# Provider y -> x
|
||||
_create_slow_delivery_notification(current_provider.identifier)
|
||||
_create_slow_delivery_notification(current_provider.identifier)
|
||||
switch_current_sms_provider_on_slow_delivery()
|
||||
|
||||
new_provider = get_current_provider('sms')
|
||||
assert new_provider.identifier != current_provider.identifier
|
||||
|
||||
# Expect to stay on provider x
|
||||
switch_current_sms_provider_on_slow_delivery()
|
||||
current_provider = get_current_provider('sms')
|
||||
assert starting_provider.identifier == current_provider.identifier
|
||||
|
||||
@@ -117,13 +117,15 @@ def sample_sms_code(notify_db,
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def sample_service(notify_db,
|
||||
notify_db_session,
|
||||
service_name="Sample service",
|
||||
user=None,
|
||||
restricted=False,
|
||||
limit=1000,
|
||||
email_from=None):
|
||||
def sample_service(
|
||||
notify_db,
|
||||
notify_db_session,
|
||||
service_name="Sample service",
|
||||
user=None,
|
||||
restricted=False,
|
||||
limit=1000,
|
||||
email_from=None
|
||||
):
|
||||
if user is None:
|
||||
user = create_user()
|
||||
if email_from is None:
|
||||
@@ -146,17 +148,19 @@ def sample_service(notify_db,
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def sample_template(notify_db,
|
||||
notify_db_session,
|
||||
template_name="Template Name",
|
||||
template_type="sms",
|
||||
content="This is a template:\nwith a newline",
|
||||
archived=False,
|
||||
subject_line='Subject',
|
||||
user=None,
|
||||
service=None,
|
||||
created_by=None,
|
||||
process_type='normal'):
|
||||
def sample_template(
|
||||
notify_db,
|
||||
notify_db_session,
|
||||
template_name="Template Name",
|
||||
template_type="sms",
|
||||
content="This is a template:\nwith a newline",
|
||||
archived=False,
|
||||
subject_line='Subject',
|
||||
user=None,
|
||||
service=None,
|
||||
created_by=None,
|
||||
process_type='normal'
|
||||
):
|
||||
if user is None:
|
||||
user = create_user()
|
||||
if service is None:
|
||||
@@ -421,23 +425,25 @@ def sample_notification_with_job(
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def sample_notification(notify_db,
|
||||
notify_db_session,
|
||||
service=None,
|
||||
template=None,
|
||||
job=None,
|
||||
job_row_number=None,
|
||||
to_field=None,
|
||||
status='created',
|
||||
reference=None,
|
||||
created_at=None,
|
||||
sent_at=None,
|
||||
billable_units=1,
|
||||
personalisation=None,
|
||||
api_key_id=None,
|
||||
key_type=KEY_TYPE_NORMAL,
|
||||
sent_by=None,
|
||||
client_reference=None):
|
||||
def sample_notification(
|
||||
notify_db,
|
||||
notify_db_session,
|
||||
service=None,
|
||||
template=None,
|
||||
job=None,
|
||||
job_row_number=None,
|
||||
to_field=None,
|
||||
status='created',
|
||||
reference=None,
|
||||
created_at=None,
|
||||
sent_at=None,
|
||||
billable_units=1,
|
||||
personalisation=None,
|
||||
api_key_id=None,
|
||||
key_type=KEY_TYPE_NORMAL,
|
||||
sent_by=None,
|
||||
client_reference=None
|
||||
):
|
||||
if created_at is None:
|
||||
created_at = datetime.utcnow()
|
||||
if service is None:
|
||||
|
||||
@@ -40,9 +40,12 @@ from app.dao.notifications_dao import (
|
||||
dao_delete_notifications_and_history_by_id,
|
||||
dao_timeout_notifications,
|
||||
get_financial_year,
|
||||
get_april_fools)
|
||||
get_april_fools,
|
||||
is_delivery_slow_for_provider
|
||||
)
|
||||
|
||||
from app.dao.services_dao import dao_update_service
|
||||
from tests.app.db import create_notification
|
||||
from tests.app.conftest import (
|
||||
sample_notification,
|
||||
sample_template,
|
||||
@@ -1422,3 +1425,130 @@ def test_get_total_sent_notifications_for_email_excludes_sms_counts(
|
||||
|
||||
total_count = get_total_sent_notifications_in_date_range(start_date, end_date, 'email')
|
||||
assert total_count == 2
|
||||
|
||||
|
||||
@freeze_time("2016-01-10 12:00:00.000000")
|
||||
def test_slow_provider_delivery_returns_for_sent_notifications(
|
||||
sample_template
|
||||
):
|
||||
now = datetime.utcnow()
|
||||
one_minute_from_now = now + timedelta(minutes=1)
|
||||
five_minutes_from_now = now + timedelta(minutes=5)
|
||||
|
||||
notification_five_minutes_to_deliver = partial(
|
||||
create_notification,
|
||||
template=sample_template,
|
||||
status='delivered',
|
||||
sent_by='mmg',
|
||||
updated_at=five_minutes_from_now
|
||||
)
|
||||
|
||||
notification_five_minutes_to_deliver(sent_at=now)
|
||||
notification_five_minutes_to_deliver(sent_at=one_minute_from_now)
|
||||
notification_five_minutes_to_deliver(sent_at=one_minute_from_now)
|
||||
|
||||
slow_delivery = is_delivery_slow_for_provider(
|
||||
sent_at=one_minute_from_now,
|
||||
provider='mmg',
|
||||
threshold=2,
|
||||
delivery_time=timedelta(minutes=3),
|
||||
service_id=sample_template.service.id,
|
||||
template_id=sample_template.id
|
||||
)
|
||||
|
||||
assert slow_delivery
|
||||
|
||||
|
||||
@freeze_time("2016-01-10 12:00:00.000000")
|
||||
def test_slow_provider_delivery_observes_threshold(
|
||||
sample_template
|
||||
):
|
||||
now = datetime.utcnow()
|
||||
five_minutes_from_now = now + timedelta(minutes=5)
|
||||
|
||||
notification_five_minutes_to_deliver = partial(
|
||||
create_notification,
|
||||
template=sample_template,
|
||||
status='delivered',
|
||||
sent_at=now,
|
||||
sent_by='mmg',
|
||||
updated_at=five_minutes_from_now
|
||||
)
|
||||
|
||||
notification_five_minutes_to_deliver()
|
||||
notification_five_minutes_to_deliver()
|
||||
|
||||
slow_delivery = is_delivery_slow_for_provider(
|
||||
sent_at=now,
|
||||
provider='mmg',
|
||||
threshold=3,
|
||||
delivery_time=timedelta(minutes=5),
|
||||
service_id=sample_template.service.id,
|
||||
template_id=sample_template.id
|
||||
)
|
||||
|
||||
assert not slow_delivery
|
||||
|
||||
|
||||
@freeze_time("2016-01-10 12:00:00.000000")
|
||||
def test_slow_provider_delivery_returns_for_delivered_notifications_only(
|
||||
sample_template
|
||||
):
|
||||
now = datetime.utcnow()
|
||||
five_minutes_from_now = now + timedelta(minutes=5)
|
||||
|
||||
notification_five_minutes_to_deliver = partial(
|
||||
create_notification,
|
||||
template=sample_template,
|
||||
sent_at=now,
|
||||
sent_by='firetext',
|
||||
created_at=now,
|
||||
updated_at=five_minutes_from_now
|
||||
)
|
||||
|
||||
notification_five_minutes_to_deliver(status='sending')
|
||||
notification_five_minutes_to_deliver(status='delivered')
|
||||
notification_five_minutes_to_deliver(status='delivered')
|
||||
|
||||
slow_delivery = is_delivery_slow_for_provider(
|
||||
sent_at=now,
|
||||
provider='firetext',
|
||||
threshold=2,
|
||||
delivery_time=timedelta(minutes=5),
|
||||
service_id=sample_template.service.id,
|
||||
template_id=sample_template.id
|
||||
)
|
||||
|
||||
assert slow_delivery
|
||||
|
||||
|
||||
@freeze_time("2016-01-10 12:00:00.000000")
|
||||
def test_slow_provider_delivery_does_not_return_for_standard_delivery_time(
|
||||
sample_template
|
||||
):
|
||||
now = datetime.utcnow()
|
||||
five_minutes_from_now = now + timedelta(minutes=5)
|
||||
|
||||
notification = partial(
|
||||
create_notification,
|
||||
template=sample_template,
|
||||
created_at=now,
|
||||
sent_at=now,
|
||||
sent_by='mmg',
|
||||
status='delivered'
|
||||
)
|
||||
|
||||
notification(updated_at=five_minutes_from_now - timedelta(seconds=1))
|
||||
notification(updated_at=five_minutes_from_now - timedelta(seconds=1))
|
||||
notification(updated_at=five_minutes_from_now)
|
||||
|
||||
slow_delivery = is_delivery_slow_for_provider(
|
||||
sent_at=now,
|
||||
provider='mmg',
|
||||
threshold=2,
|
||||
delivery_time=timedelta(minutes=5),
|
||||
service_id=sample_template.service.id,
|
||||
template_id=sample_template.id
|
||||
)
|
||||
|
||||
assert not slow_delivery
|
||||
|
||||
@@ -19,7 +19,7 @@ from app.dao.provider_details_dao import (
|
||||
)
|
||||
|
||||
|
||||
def set_primary_sms_provider(identifier='mmg'):
|
||||
def set_primary_sms_provider(identifier):
|
||||
primary_provider = get_provider_details_by_identifier(identifier)
|
||||
secondary_provider = get_alternative_sms_provider(identifier)
|
||||
|
||||
@@ -153,22 +153,28 @@ def test_toggle_sms_provider_switches_provider(
|
||||
):
|
||||
dao_toggle_sms_provider(current_sms_provider.identifier)
|
||||
new_provider = get_current_provider('sms')
|
||||
assert new_provider.identifier != current_sms_provider.identifier
|
||||
assert new_provider.priority < current_sms_provider.priority
|
||||
|
||||
old_starting_provider = get_provider_details_by_identifier(current_sms_provider.identifier)
|
||||
|
||||
assert new_provider.identifier != old_starting_provider.identifier
|
||||
assert new_provider.priority < old_starting_provider.priority
|
||||
|
||||
|
||||
def test_toggle_sms_provider_switches_when_provider_priorities_are_equal(
|
||||
restore_provider_details,
|
||||
current_sms_provider
|
||||
restore_provider_details
|
||||
):
|
||||
new_provider = get_alternative_sms_provider(current_sms_provider.identifier)
|
||||
current_sms_provider.priority = new_provider.priority
|
||||
dao_update_provider_details(current_sms_provider)
|
||||
current_provider = get_current_provider('sms')
|
||||
new_provider = get_alternative_sms_provider(current_provider.identifier)
|
||||
|
||||
dao_toggle_sms_provider(current_sms_provider.identifier)
|
||||
current_provider.priority = new_provider.priority
|
||||
dao_update_provider_details(current_provider)
|
||||
|
||||
assert new_provider.identifier != current_sms_provider.identifier
|
||||
assert new_provider.priority < current_sms_provider.priority
|
||||
dao_toggle_sms_provider(current_provider.identifier)
|
||||
|
||||
old_starting_provider = get_provider_details_by_identifier(current_provider.identifier)
|
||||
|
||||
assert new_provider.identifier != old_starting_provider.identifier
|
||||
assert new_provider.priority < old_starting_provider.priority
|
||||
|
||||
|
||||
def test_toggle_sms_provider_updates_provider_history(
|
||||
|
||||
@@ -23,7 +23,7 @@ def create_user(mobile_number="+447700900986", email="notify@digital.cabinet-off
|
||||
return user
|
||||
|
||||
|
||||
def create_service(user=None, service_name="Sample service"):
|
||||
def create_service(user=None, service_name="Sample service", service_id=None):
|
||||
service = Service(
|
||||
name=service_name,
|
||||
message_limit=1000,
|
||||
@@ -31,14 +31,15 @@ def create_service(user=None, service_name="Sample service"):
|
||||
email_from=service_name.lower().replace(' ', '.'),
|
||||
created_by=user or create_user()
|
||||
)
|
||||
dao_create_service(service, service.created_by)
|
||||
dao_create_service(service, service.created_by, service_id)
|
||||
return service
|
||||
|
||||
|
||||
def create_template(
|
||||
service,
|
||||
template_type=SMS_TYPE,
|
||||
content='Dear Sir/Madam, Hello. Yours Truly, The Government.'
|
||||
content='Dear Sir/Madam, Hello. Yours Truly, The Government.',
|
||||
template_id=None
|
||||
):
|
||||
data = {
|
||||
'name': '{} Template Name'.format(template_type),
|
||||
@@ -50,7 +51,7 @@ def create_template(
|
||||
if template_type != SMS_TYPE:
|
||||
data['subject'] = 'Template subject'
|
||||
template = Template(**data)
|
||||
dao_create_template(template)
|
||||
dao_create_template(template, template_id)
|
||||
return template
|
||||
|
||||
|
||||
@@ -63,6 +64,7 @@ def create_notification(
|
||||
reference=None,
|
||||
created_at=None,
|
||||
sent_at=None,
|
||||
updated_at=None,
|
||||
billable_units=1,
|
||||
personalisation=None,
|
||||
api_key_id=None,
|
||||
@@ -72,6 +74,11 @@ def create_notification(
|
||||
):
|
||||
if created_at is None:
|
||||
created_at = datetime.utcnow()
|
||||
|
||||
if status != 'created':
|
||||
sent_at = sent_at or datetime.utcnow()
|
||||
updated_at = updated_at or datetime.utcnow()
|
||||
|
||||
data = {
|
||||
'id': uuid.uuid4(),
|
||||
'to': to_field,
|
||||
@@ -91,7 +98,7 @@ def create_notification(
|
||||
'api_key_id': api_key_id,
|
||||
'key_type': key_type,
|
||||
'sent_by': sent_by,
|
||||
'updated_at': None,
|
||||
'updated_at': updated_at,
|
||||
'client_reference': client_reference,
|
||||
'job_row_number': job_row_number
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user