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