diff --git a/app/dao/date_util.py b/app/dao/date_util.py index 64c18e4e2..35f1de9d2 100644 --- a/app/dao/date_util.py +++ b/app/dao/date_util.py @@ -1,4 +1,4 @@ -from datetime import date, datetime, time, timedelta +from datetime import datetime, time, timedelta import pytz from notifications_utils.timezones import convert_bst_to_utc @@ -64,7 +64,7 @@ def get_current_financial_year_start_year(): def get_financial_year_for_datetime(start_date): - if type(start_date) == date: + if type(start_date) != datetime: start_date = datetime.combine(start_date, time.min) year = int(start_date.strftime('%Y')) diff --git a/app/dao/fact_billing_dao.py b/app/dao/fact_billing_dao.py index 9be5ec19f..55789c8e0 100644 --- a/app/dao/fact_billing_dao.py +++ b/app/dao/fact_billing_dao.py @@ -1,4 +1,4 @@ -from datetime import date, datetime, timedelta +from datetime import date, datetime, time, timedelta from flask import current_app from notifications_utils.timezones import convert_utc_to_bst @@ -596,7 +596,7 @@ def fetch_email_usage_for_organisation(organisation_id, start_date, end_date): def fetch_sms_rates_for_date_range(start_date, end_date): - Rate.query.filter( + return Rate.query.filter( Rate.notification_type == 'sms', Rate.valid_from >= start_date, Rate.valid_from <= end_date @@ -607,7 +607,7 @@ def fetch_sms_rates_for_date_range(start_date, end_date): def fetch_sms_billing_for_organisation(organisation_id, start_date, end_date): rates = fetch_sms_rates_for_date_range(start_date, end_date) - if len(rates) >= 1: + if len(rates) >= 1 and (convert_utc_to_bst(rates[0].valid_from)).date() != start_date: return fetch_sms_billing_for_organisation_with_rate_change(organisation_id, start_date, end_date, rates) # ASSUMPTION: AnnualBilling has been populated for year. allowance_left_at_start_date_query = fetch_sms_free_allowance_remainder_until_date(start_date).subquery() @@ -665,13 +665,25 @@ def fetch_sms_billing_for_organisation_with_rate_change(organisation_id, start_d sms_billings_for_organisation = [] dates = [start_date, end_date] for rate in rates: - dates.append(rate.valid_from) - dates = dates.sorted() + dates.append(convert_utc_to_bst(rate.valid_from).date()) + dates.sort() for i, date_ in enumerate(dates): - part_of_billing_data = fetch_sms_billing_for_organisation(organisation_id, date_, dates[i+1]) + loop_start_date = date_ + if i == len(dates) - 1: + break + elif i == len(dates) - 2: + loop_end_date = dates[i+1] + else: + loop_end_date = dates[i+1] - timedelta(days=1) + part_of_billing_data = fetch_sms_billing_for_organisation( + organisation_id, + loop_start_date, + loop_end_date + ) sms_billings_for_organisation.append(part_of_billing_data) - # WIP think how to unite that data - do we give admin multiple dicts and then admin counts them, or do we somehow - # mash it in here? + import pdb; pdb.set_trace() + # now we need to add costs from those data points, take freshest allowance info etc. + return sms_billings_for_organisation def fetch_usage_year_for_organisation(organisation_id, year): diff --git a/tests/app/dao/test_ft_billing_dao.py b/tests/app/dao/test_ft_billing_dao.py index 8f305b48c..49eccd8a9 100644 --- a/tests/app/dao/test_ft_billing_dao.py +++ b/tests/app/dao/test_ft_billing_dao.py @@ -771,9 +771,10 @@ def test_fetch_usage_year_for_organisation(notify_db_session): assert third_row['emails_sent'] == 0 +@freeze_time('2022-04-24 13:30') def test_fetch_usage_year_for_organisation_populates_ft_billing_for_today(notify_db_session): - create_letter_rate(start_date=datetime.utcnow() - timedelta(days=1)) - create_rate(start_date=datetime.utcnow() - timedelta(days=1), value=0.65, notification_type='sms') + create_letter_rate(datetime(2022, 3, 31, 23, 00)) + create_rate(start_date=datetime(2022, 3, 31, 23, 00), value=0.65, notification_type='sms') new_org = create_organisation(name='New organisation') service = create_service() template = create_template(service=service) @@ -790,6 +791,28 @@ def test_fetch_usage_year_for_organisation_populates_ft_billing_for_today(notify assert FactBilling.query.count() == 1 +@freeze_time('2022-05-24 13:30') +def test_fetch_usage_year_for_organisation_when_more_than_one_rate_per_financial_year(notify_db_session): + + current_year = datetime.utcnow().year + with freeze_time('2022-04-02T00:01:00'): + create_rate(start_date=datetime(2022, 3, 31, 23, 00), value=0.0161, notification_type='sms') + new_org = create_organisation(name='New organisation') + service = create_service() + template = create_template(service=service) + dao_add_service_to_organisation(service=service, organisation_id=new_org.id) + create_annual_billing(service_id=service.id, free_sms_fragment_limit=0, financial_year_start=current_year) + create_notification(template=template, status='delivered') + + assert FactBilling.query.count() == 0 + create_rate(start_date=datetime(2022, 4, 30, 23, 00), value=0.0172, notification_type='sms') + create_notification(template=template, status='delivered') + + results = fetch_usage_year_for_organisation(organisation_id=new_org.id, year=current_year) + assert len(results) == 1 + assert FactBilling.query.count() == 1 + + @freeze_time('2020-02-27 13:30') def test_fetch_usage_year_for_organisation_only_returns_data_for_live_services(notify_db_session): org = create_organisation(name='Organisation without live services')