From 6727f0e0f518202a4cac5f5b0750aed07228e303 Mon Sep 17 00:00:00 2001 From: Katie Smith Date: Wed, 26 Sep 2018 11:28:59 +0100 Subject: [PATCH] Update ft_billing DAO functions to use postage * Updated the 'fetch_billing_data_for_day' DAO function to take postage into account * Updated the 'update_fact_billing' DAO function to insert postage for new rows. When updating rows which are identical apart from the postage, the original row will be kept. (This behaviour will change once postage is added to the primary key - at this point, upserting will add a new row.) * Also changed some fixtures / test set up functions to take postage into account --- app/dao/fact_billing_dao.py | 10 +++++-- tests/app/billing/test_billing.py | 15 ++++++---- tests/app/celery/test_reporting_tasks.py | 38 ++++++++++++++++++++++++ tests/app/conftest.py | 6 ++-- tests/app/dao/test_ft_billing_dao.py | 34 +++++++++++++++++++-- tests/app/db.py | 6 ++-- 6 files changed, 95 insertions(+), 14 deletions(-) diff --git a/app/dao/fact_billing_dao.py b/app/dao/fact_billing_dao.py index 0c8d636a8..a8ebb850c 100644 --- a/app/dao/fact_billing_dao.py +++ b/app/dao/fact_billing_dao.py @@ -169,6 +169,7 @@ def fetch_billing_data_for_day(process_day, service_id=None): func.sum(table.billable_units).label('billable_units'), func.count().label('notifications_sent'), Service.crown, + func.coalesce(table.postage, 'none').label('postage') ).filter( table.status.in_(NOTIFICATION_STATUS_TYPES_BILLABLE), table.key_type != KEY_TYPE_TEST, @@ -182,7 +183,8 @@ def fetch_billing_data_for_day(process_day, service_id=None): 'letter_page_count', table.rate_multiplier, table.international, - Service.crown + Service.crown, + table.postage, ).join( Service ) @@ -254,7 +256,8 @@ def update_fact_billing(data, process_day): international=billing_record.international, billable_units=billing_record.billable_units, notifications_sent=billing_record.notifications_sent, - rate=billing_record.rate + rate=billing_record.rate, + postage=billing_record.postage, ) stmt = stmt.on_conflict_do_update( @@ -279,6 +282,7 @@ def create_billing_record(data, rate, process_day): international=data.international, billable_units=data.billable_units, notifications_sent=data.notifications_sent, - rate=rate + rate=rate, + postage=data.postage, ) return billing_record diff --git a/tests/app/billing/test_billing.py b/tests/app/billing/test_billing.py index 3ea91bdda..9dcb04904 100644 --- a/tests/app/billing/test_billing.py +++ b/tests/app/billing/test_billing.py @@ -200,7 +200,8 @@ def test_get_yearly_usage_by_monthly_from_ft_billing(client, notify_db_session): template=letter_template, notification_type='letter', billable_unit=1, - rate=0.33) + rate=0.33, + postage='second') response = client.get('service/{}/billing/ft-monthly-usage?year=2016'.format(service.id), headers=[('Content-Type', 'application/json'), create_authorization_header()]) @@ -257,7 +258,8 @@ def set_up_yearly_data(): service=service, template=letter_template, notification_type='letter', - rate=0.33) + rate=0.33, + postage='second') start_date, end_date = get_month_start_and_end_date_in_utc(datetime(2016, int(mon), 1)) return service @@ -429,7 +431,8 @@ def set_up_data_for_all_cases(): international=False, rate=0.33, billable_unit=1, - notifications_sent=1) + notifications_sent=1, + postage='second') create_ft_billing(bst_date='2018-05-17', notification_type='letter', template=letter_template, @@ -438,7 +441,8 @@ def set_up_data_for_all_cases(): international=False, rate=0.36, billable_unit=2, - notifications_sent=1) + notifications_sent=1, + postage='second') create_ft_billing(bst_date='2018-05-18', notification_type='letter', template=letter_template, @@ -447,5 +451,6 @@ def set_up_data_for_all_cases(): international=False, rate=0.39, billable_unit=3, - notifications_sent=1) + notifications_sent=1, + postage='second') return service diff --git a/tests/app/celery/test_reporting_tasks.py b/tests/app/celery/test_reporting_tasks.py index 8da479555..2fa8b2d15 100644 --- a/tests/app/celery/test_reporting_tasks.py +++ b/tests/app/celery/test_reporting_tasks.py @@ -210,6 +210,44 @@ def test_create_nightly_billing_letter( assert record.rate_multiplier == 2.0 +def test_create_nightly_billing_different_letter_postage( + notify_db_session, + sample_letter_template, + mocker): + yesterday = datetime.now() - timedelta(days=1) + + mocker.patch('app.dao.fact_billing_dao.get_rate', side_effect=mocker_get_rate) + + create_notification( + created_at=yesterday, + template=sample_letter_template, + status='delivered', + sent_by='dvla', + billable_units=2, + postage='first' + ) + create_notification( + created_at=yesterday, + template=sample_letter_template, + status='delivered', + sent_by='dvla', + billable_units=2, + postage='second' + ) + + records = FactBilling.query.all() + assert len(records) == 0 + # Celery expects the arguments to be a string or primitive type. + yesterday_str = datetime.strftime(yesterday, "%Y-%m-%d") + create_nightly_billing(yesterday_str) + + # ft_billing rows will not get upserted since postage is not part of the primary key + record = FactBilling.query.one() + assert record.notification_type == LETTER_TYPE + assert record.bst_date == datetime.date(yesterday) + assert record.postage == 'first' + + def test_create_nightly_billing_null_sent_by_sms( sample_service, sample_template, diff --git a/tests/app/conftest.py b/tests/app/conftest.py index 61d018bc3..a1d71d2dd 100644 --- a/tests/app/conftest.py +++ b/tests/app/conftest.py @@ -535,7 +535,8 @@ def sample_notification( client_reference=None, rate_multiplier=1.0, scheduled_for=None, - normalised_to=None + normalised_to=None, + postage=None, ): if created_at is None: created_at = datetime.utcnow() @@ -580,7 +581,8 @@ def sample_notification( 'updated_at': created_at if status in NOTIFICATION_STATUS_TYPES_COMPLETED else None, 'client_reference': client_reference, 'rate_multiplier': rate_multiplier, - 'normalised_to': normalised_to + 'normalised_to': normalised_to, + 'postage': postage, } if job_row_number is not None: data['job_row_number'] = job_row_number diff --git a/tests/app/dao/test_ft_billing_dao.py b/tests/app/dao/test_ft_billing_dao.py index 26a1efe07..696b47558 100644 --- a/tests/app/dao/test_ft_billing_dao.py +++ b/tests/app/dao/test_ft_billing_dao.py @@ -50,12 +50,14 @@ def set_up_yearly_data(): service=service, template=letter_template, notification_type='letter', - rate=0.33) + rate=0.33, + postage='second') create_ft_billing(bst_date='{}-{}-{}'.format(year, mon, d), service=service, template=letter_template, notification_type='letter', - rate=0.30) + rate=0.30, + postage='second') return service @@ -190,6 +192,34 @@ def test_fetch_billing_data_for_day_is_grouped_by_notification_type(notify_db_se assert len(notification_types) == 3 +def test_fetch_billing_data_for_day_groups_by_postage(notify_db_session): + service = create_service() + letter_template = create_template(service=service, template_type='letter') + email_template = create_template(service=service, template_type='email') + create_notification(template=letter_template, status='delivered', postage='first') + create_notification(template=letter_template, status='delivered', postage='first') + create_notification(template=letter_template, status='delivered', postage='second') + create_notification(template=email_template, status='delivered') + + today = convert_utc_to_bst(datetime.utcnow()) + results = fetch_billing_data_for_day(today) + assert len(results) == 3 + + +def test_fetch_billing_data_for_day_sets_postage_for_emails_and_sms_to_none(notify_db_session): + service = create_service() + sms_template = create_template(service=service, template_type='sms') + email_template = create_template(service=service, template_type='email') + create_notification(template=sms_template, status='delivered') + create_notification(template=email_template, status='delivered') + + today = convert_utc_to_bst(datetime.utcnow()) + results = fetch_billing_data_for_day(today) + assert len(results) == 2 + assert results[0].postage == 'none' + assert results[1].postage == 'none' + + def test_fetch_billing_data_for_day_returns_empty_list(notify_db_session): today = convert_utc_to_bst(datetime.utcnow()) results = fetch_billing_data_for_day(today) diff --git a/tests/app/db.py b/tests/app/db.py index 5c4e5f674..a0d68a8b9 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -512,7 +512,8 @@ def create_ft_billing(bst_date, international=False, rate=0, billable_unit=1, - notifications_sent=1 + notifications_sent=1, + postage='none', ): if not service: service = create_service() @@ -528,7 +529,8 @@ def create_ft_billing(bst_date, international=international, rate=rate, billable_units=billable_unit, - notifications_sent=notifications_sent) + notifications_sent=notifications_sent, + postage=postage) db.session.add(data) db.session.commit() return data