mirror of
https://github.com/GSA/notifications-api.git
synced 2026-08-20 22:39:43 -04:00
Merge pull request #2096 from alphagov/new_letter_rates_from_10_2018
Introduce new letter rates, valid from 01.10.2018
This commit is contained in:
@@ -342,6 +342,9 @@ class Development(Config):
|
|||||||
SECRET_KEY = 'dev-notify-secret-key'
|
SECRET_KEY = 'dev-notify-secret-key'
|
||||||
DANGEROUS_SALT = 'dev-notify-salt'
|
DANGEROUS_SALT = 'dev-notify-salt'
|
||||||
|
|
||||||
|
MMG_INBOUND_SMS_AUTH = ['testkey']
|
||||||
|
MMG_INBOUND_SMS_USERNAME = ['username']
|
||||||
|
|
||||||
NOTIFY_ENVIRONMENT = 'development'
|
NOTIFY_ENVIRONMENT = 'development'
|
||||||
NOTIFY_LOG_PATH = 'application.log'
|
NOTIFY_LOG_PATH = 'application.log'
|
||||||
NOTIFICATION_QUEUE_PREFIX = 'development'
|
NOTIFICATION_QUEUE_PREFIX = 'development'
|
||||||
@@ -392,8 +395,6 @@ class Test(Development):
|
|||||||
|
|
||||||
SMS_INBOUND_WHITELIST = ['203.0.113.195']
|
SMS_INBOUND_WHITELIST = ['203.0.113.195']
|
||||||
FIRETEXT_INBOUND_SMS_AUTH = ['testkey']
|
FIRETEXT_INBOUND_SMS_AUTH = ['testkey']
|
||||||
MMG_INBOUND_SMS_AUTH = ['testkey']
|
|
||||||
MMG_INBOUND_SMS_USERNAME = ['username']
|
|
||||||
TEMPLATE_PREVIEW_API_HOST = 'http://localhost:9999'
|
TEMPLATE_PREVIEW_API_HOST = 'http://localhost:9999'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ def fetch_billing_data_for_day(process_day, service_id=None):
|
|||||||
def get_rates_for_billing():
|
def get_rates_for_billing():
|
||||||
non_letter_rates = [(r.notification_type, r.valid_from, r.rate) for r in
|
non_letter_rates = [(r.notification_type, r.valid_from, r.rate) for r in
|
||||||
Rate.query.order_by(desc(Rate.valid_from)).all()]
|
Rate.query.order_by(desc(Rate.valid_from)).all()]
|
||||||
letter_rates = [(r.start_date, r.crown, r.sheet_count, r.rate) for r in
|
letter_rates = [(r.start_date, r.crown, r.sheet_count, r.rate, r.post_class) for r in
|
||||||
LetterRate.query.order_by(desc(LetterRate.start_date)).all()]
|
LetterRate.query.order_by(desc(LetterRate.start_date)).all()]
|
||||||
return non_letter_rates, letter_rates
|
return non_letter_rates, letter_rates
|
||||||
|
|
||||||
@@ -211,13 +211,18 @@ def get_service_ids_that_need_billing_populated(start_date, end_date):
|
|||||||
).distinct().all()
|
).distinct().all()
|
||||||
|
|
||||||
|
|
||||||
def get_rate(non_letter_rates, letter_rates, notification_type, date, crown=None, letter_page_count=None):
|
def get_rate(
|
||||||
|
non_letter_rates, letter_rates, notification_type, date, crown=None, letter_page_count=None, post_class='second'
|
||||||
|
):
|
||||||
if notification_type == LETTER_TYPE:
|
if notification_type == LETTER_TYPE:
|
||||||
if letter_page_count == 0:
|
if letter_page_count == 0:
|
||||||
return 0
|
return 0
|
||||||
return next(r[3] for r in letter_rates if date > r[0] and crown == r[1] and letter_page_count == r[2])
|
return next(
|
||||||
|
r[3] for r in letter_rates if date >= r[0] and crown == r[1]
|
||||||
|
and letter_page_count == r[2] and post_class == r[4]
|
||||||
|
)
|
||||||
elif notification_type == SMS_TYPE:
|
elif notification_type == SMS_TYPE:
|
||||||
return next(r[2] for r in non_letter_rates if notification_type == r[0] and date > r[1])
|
return next(r[2] for r in non_letter_rates if notification_type == r[0] and date >= r[1])
|
||||||
else:
|
else:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -229,7 +234,8 @@ def update_fact_billing(data, process_day):
|
|||||||
data.notification_type,
|
data.notification_type,
|
||||||
process_day,
|
process_day,
|
||||||
data.crown,
|
data.crown,
|
||||||
data.letter_page_count)
|
data.letter_page_count,
|
||||||
|
"second")
|
||||||
billing_record = create_billing_record(data, rate, process_day)
|
billing_record = create_billing_record(data, rate, process_day)
|
||||||
table = FactBilling.__table__
|
table = FactBilling.__table__
|
||||||
'''
|
'''
|
||||||
|
|||||||
77
migrations/versions/0229_new_letter_rates.py
Normal file
77
migrations/versions/0229_new_letter_rates.py
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: 0229_new_letter_rates
|
||||||
|
Revises: 0228_notification_postage
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
revision = '0229_new_letter_rates'
|
||||||
|
down_revision = '0228_notification_postage'
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
from datetime import datetime
|
||||||
|
from alembic import op
|
||||||
|
from sqlalchemy.sql import text
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
START = datetime(2018, 9, 30, 23, 0)
|
||||||
|
|
||||||
|
NEW_RATES = [
|
||||||
|
(uuid.uuid4(), START, 1, 0.30, False, 'second'),
|
||||||
|
(uuid.uuid4(), START, 2, 0.35, True, 'second'),
|
||||||
|
(uuid.uuid4(), START, 2, 0.35, False, 'second'),
|
||||||
|
(uuid.uuid4(), START, 3, 0.40, True, 'second'),
|
||||||
|
(uuid.uuid4(), START, 3, 0.40, False, 'second'),
|
||||||
|
(uuid.uuid4(), START, 4, 0.45, True, 'second'),
|
||||||
|
(uuid.uuid4(), START, 4, 0.45, False, 'second'),
|
||||||
|
(uuid.uuid4(), START, 5, 0.50, True, 'second'),
|
||||||
|
(uuid.uuid4(), START, 5, 0.50, False, 'second'),
|
||||||
|
(uuid.uuid4(), START, 1, 0.56, True, 'first'),
|
||||||
|
(uuid.uuid4(), START, 1, 0.56, False, 'first'),
|
||||||
|
(uuid.uuid4(), START, 2, 0.61, True, 'first'),
|
||||||
|
(uuid.uuid4(), START, 2, 0.61, False, 'first'),
|
||||||
|
(uuid.uuid4(), START, 3, 0.66, True, 'first'),
|
||||||
|
(uuid.uuid4(), START, 3, 0.66, False, 'first'),
|
||||||
|
(uuid.uuid4(), START, 4, 0.71, True, 'first'),
|
||||||
|
(uuid.uuid4(), START, 4, 0.71, False, 'first'),
|
||||||
|
(uuid.uuid4(), START, 5, 0.76, True, 'first'),
|
||||||
|
(uuid.uuid4(), START, 5, 0.76, False, 'first'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
conn = op.get_bind()
|
||||||
|
conn.execute(text("""
|
||||||
|
update
|
||||||
|
letter_rates
|
||||||
|
set
|
||||||
|
end_date = :start
|
||||||
|
where
|
||||||
|
rate != 0.30
|
||||||
|
"""), start=START)
|
||||||
|
|
||||||
|
for id, start_date, sheet_count, rate, crown, post_class in NEW_RATES:
|
||||||
|
conn.execute(text("""
|
||||||
|
INSERT INTO letter_rates (id, start_date, sheet_count, rate, crown, post_class)
|
||||||
|
VALUES (:id, :start_date, :sheet_count, :rate, :crown, :post_class)
|
||||||
|
"""), id=id, start_date=start_date, sheet_count=sheet_count, rate=rate, crown=crown, post_class=post_class)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
conn = op.get_bind()
|
||||||
|
conn.execute(text("""
|
||||||
|
delete from
|
||||||
|
letter_rates
|
||||||
|
where
|
||||||
|
start_date = :start
|
||||||
|
"""), start=START)
|
||||||
|
|
||||||
|
conn.execute(text("""
|
||||||
|
update
|
||||||
|
letter_rates
|
||||||
|
set
|
||||||
|
end_date = null
|
||||||
|
where
|
||||||
|
end_date = :start
|
||||||
|
"""), start=START)
|
||||||
@@ -23,7 +23,9 @@ def test_reporting_should_have_decorated_tasks_functions():
|
|||||||
assert create_nightly_billing.__wrapped__.__name__ == 'create_nightly_billing'
|
assert create_nightly_billing.__wrapped__.__name__ == 'create_nightly_billing'
|
||||||
|
|
||||||
|
|
||||||
def mocker_get_rate(non_letter_rates, letter_rates, notification_type, date, crown=None, rate_multiplier=None):
|
def mocker_get_rate(
|
||||||
|
non_letter_rates, letter_rates, notification_type, date, crown=None, rate_multiplier=None, post_class="second"
|
||||||
|
):
|
||||||
if notification_type == LETTER_TYPE:
|
if notification_type == LETTER_TYPE:
|
||||||
return Decimal(2.1)
|
return Decimal(2.1)
|
||||||
elif notification_type == SMS_TYPE:
|
elif notification_type == SMS_TYPE:
|
||||||
@@ -319,9 +321,10 @@ def test_get_rate_for_letter_latest(notify_db_session):
|
|||||||
non_letter_rates = [(r.notification_type, r.valid_from, r.rate) for r in
|
non_letter_rates = [(r.notification_type, r.valid_from, r.rate) for r in
|
||||||
Rate.query.order_by(desc(Rate.valid_from)).all()]
|
Rate.query.order_by(desc(Rate.valid_from)).all()]
|
||||||
|
|
||||||
# letter rates should be passed into the get_rate function as a tuple of start_date, crown, sheet_count & rate
|
# letter rates should be passed into the get_rate function as a tuple of start_date, crown, sheet_count,
|
||||||
new_letter_rate = (datetime(2017, 12, 1), True, 1, Decimal(0.33))
|
# rate and post_class
|
||||||
old_letter_rate = (datetime(2016, 12, 1), True, 1, Decimal(0.30))
|
new_letter_rate = (datetime(2017, 12, 1), True, 1, Decimal(0.33), 'second')
|
||||||
|
old_letter_rate = (datetime(2016, 12, 1), True, 1, Decimal(0.30), 'second')
|
||||||
letter_rates = [new_letter_rate, old_letter_rate]
|
letter_rates = [new_letter_rate, old_letter_rate]
|
||||||
|
|
||||||
rate = get_rate(non_letter_rates, letter_rates, LETTER_TYPE, datetime(2018, 1, 1), True, 1)
|
rate = get_rate(non_letter_rates, letter_rates, LETTER_TYPE, datetime(2018, 1, 1), True, 1)
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ from decimal import Decimal
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from freezegun import freeze_time
|
from freezegun import freeze_time
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
from app.dao.fact_billing_dao import (
|
from app.dao.fact_billing_dao import (
|
||||||
delete_billing_data_for_service_for_day,
|
delete_billing_data_for_service_for_day,
|
||||||
@@ -228,7 +230,7 @@ def test_get_rates_for_billing(notify_db_session):
|
|||||||
non_letter_rates, letter_rates = get_rates_for_billing()
|
non_letter_rates, letter_rates = get_rates_for_billing()
|
||||||
|
|
||||||
assert len(non_letter_rates) == 3
|
assert len(non_letter_rates) == 3
|
||||||
assert len(letter_rates) == 10
|
assert len(letter_rates) == 29
|
||||||
|
|
||||||
|
|
||||||
def test_get_rate(notify_db_session):
|
def test_get_rate(notify_db_session):
|
||||||
@@ -248,6 +250,20 @@ def test_get_rate(notify_db_session):
|
|||||||
assert letter_rate == Decimal('0.3')
|
assert letter_rate == Decimal('0.3')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("letter_post_class,expected_rate", [("first", "0.61"), ("second", "0.35")])
|
||||||
|
def test_get_rate_filters_letters_by_post_class(notify_db_session, letter_post_class, expected_rate):
|
||||||
|
non_letter_rates, letter_rates = get_rates_for_billing()
|
||||||
|
rate = get_rate(non_letter_rates, letter_rates, "letter", datetime(2018, 10, 1), True, 2, letter_post_class)
|
||||||
|
assert rate == Decimal(expected_rate)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("date,expected_rate", [(datetime(2018, 9, 30), '0.33'), (datetime(2018, 10, 1), '0.35')])
|
||||||
|
def test_get_rate_chooses_right_rate_depending_on_date(notify_db_session, date, expected_rate):
|
||||||
|
non_letter_rates, letter_rates = get_rates_for_billing()
|
||||||
|
rate = get_rate(non_letter_rates, letter_rates, "letter", date, True, 2, "second")
|
||||||
|
assert rate == Decimal(expected_rate)
|
||||||
|
|
||||||
|
|
||||||
def test_get_rate_for_letters_when_page_count_is_zero(notify_db_session):
|
def test_get_rate_for_letters_when_page_count_is_zero(notify_db_session):
|
||||||
non_letter_rates, letter_rates = get_rates_for_billing()
|
non_letter_rates, letter_rates = get_rates_for_billing()
|
||||||
letter_rate = get_rate(non_letter_rates=non_letter_rates, letter_rates=letter_rates,
|
letter_rate = get_rate(non_letter_rates=non_letter_rates, letter_rates=letter_rates,
|
||||||
|
|||||||
Reference in New Issue
Block a user