mirror of
https://github.com/GSA/notifications-api.git
synced 2026-09-09 06:33:12 -04:00
Merge pull request #1935 from alphagov/new-letter-billing
Migration for new letter pricing
This commit is contained in:
@@ -1,23 +0,0 @@
|
|||||||
from app import db
|
|
||||||
from app.dao.dao_utils import transactional
|
|
||||||
from app.models import LetterRate
|
|
||||||
|
|
||||||
|
|
||||||
@transactional
|
|
||||||
def dao_create_letter_rate(letter_rate):
|
|
||||||
db.session.add(letter_rate)
|
|
||||||
|
|
||||||
|
|
||||||
def get_letter_rates_for_daterange(date, crown, sheet_count, post_class='second'):
|
|
||||||
rates = LetterRate.query.filter(
|
|
||||||
LetterRate.start_date <= date
|
|
||||||
).filter((LetterRate.end_date == None) | # noqa
|
|
||||||
(LetterRate.end_date > date)
|
|
||||||
).filter(
|
|
||||||
LetterRate.crown == crown
|
|
||||||
).filter(
|
|
||||||
LetterRate.sheet_count == sheet_count
|
|
||||||
).filter(
|
|
||||||
LetterRate.post_class == post_class
|
|
||||||
).all()
|
|
||||||
return rates
|
|
||||||
37
migrations/versions/0202_new_letter_pricing.py
Normal file
37
migrations/versions/0202_new_letter_pricing.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: 0202_new_letter_pricing
|
||||||
|
Revises: 0201_another_letter_org
|
||||||
|
Create Date: 2017-07-09 12:44:16.815039
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
revision = '0202_new_letter_pricing'
|
||||||
|
down_revision = '0201_another_letter_org'
|
||||||
|
|
||||||
|
import uuid
|
||||||
|
from datetime import datetime
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
|
||||||
|
start = datetime(2018, 6, 30, 23, 0)
|
||||||
|
|
||||||
|
NEW_RATES = [
|
||||||
|
(uuid.uuid4(), start, 4, 0.39, True, 'second'),
|
||||||
|
(uuid.uuid4(), start, 4, 0.51, False, 'second'),
|
||||||
|
(uuid.uuid4(), start, 5, 0.42, True, 'second'),
|
||||||
|
(uuid.uuid4(), start, 5, 0.57, False, 'second'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
conn = op.get_bind()
|
||||||
|
for id, start_date, sheet_count, rate, crown, post_class in NEW_RATES:
|
||||||
|
conn.execute("""
|
||||||
|
INSERT INTO letter_rates (id, start_date, sheet_count, rate, crown, post_class)
|
||||||
|
VALUES ('{}', '{}', '{}', '{}', '{}', '{}')
|
||||||
|
""".format(id, start_date, sheet_count, rate, crown, post_class))
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
pass
|
||||||
@@ -17,7 +17,6 @@ from tests.app.db import (
|
|||||||
create_rate,
|
create_rate,
|
||||||
create_monthly_billing_entry,
|
create_monthly_billing_entry,
|
||||||
create_annual_billing,
|
create_annual_billing,
|
||||||
create_letter_rate,
|
|
||||||
create_template,
|
create_template,
|
||||||
create_service,
|
create_service,
|
||||||
create_ft_billing
|
create_ft_billing
|
||||||
@@ -47,8 +46,6 @@ def test_get_yearly_billing_summary_returns_correct_breakdown(client, sample_tem
|
|||||||
template=sample_template, created_at=IN_JUN_2016,
|
template=sample_template, created_at=IN_JUN_2016,
|
||||||
billable_units=2, rate_multiplier=3, status='delivered'
|
billable_units=2, rate_multiplier=3, status='delivered'
|
||||||
)
|
)
|
||||||
create_letter_rate(crown=False, start_date=IN_MAY_2016, end_date=IN_JUN_2016)
|
|
||||||
create_letter_rate(crown=False, start_date=IN_JUN_2016, rate=0.41)
|
|
||||||
|
|
||||||
letter_template = create_template(service=sample_template.service, template_type=LETTER_TYPE)
|
letter_template = create_template(service=sample_template.service, template_type=LETTER_TYPE)
|
||||||
create_notification(template=letter_template, created_at=IN_MAY_2016, status='delivered', billable_units=1)
|
create_notification(template=letter_template, created_at=IN_MAY_2016, status='delivered', billable_units=1)
|
||||||
@@ -76,7 +73,7 @@ def test_get_yearly_billing_summary_returns_correct_breakdown(client, sample_tem
|
|||||||
'notification_type': LETTER_TYPE,
|
'notification_type': LETTER_TYPE,
|
||||||
'billing_units': 2,
|
'billing_units': 2,
|
||||||
'rate': 0,
|
'rate': 0,
|
||||||
'letter_total': 0.72
|
'letter_total': 0.66
|
||||||
})
|
})
|
||||||
_assert_dict_equals(resp_json[2], {
|
_assert_dict_equals(resp_json[2], {
|
||||||
'notification_type': SMS_TYPE,
|
'notification_type': SMS_TYPE,
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ from app.models import (
|
|||||||
)
|
)
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
import pytest
|
import pytest
|
||||||
from app.dao.letter_rate_dao import dao_create_letter_rate
|
|
||||||
from app.models import LetterRate, Rate
|
from app.models import LetterRate, Rate
|
||||||
from app import db
|
from app import db
|
||||||
from freezegun import freeze_time
|
from freezegun import freeze_time
|
||||||
@@ -316,38 +315,20 @@ def test_create_nightly_billing_consolidate_from_3_days_delta(
|
|||||||
assert records[-1].bst_date == date(2018, 1, 14)
|
assert records[-1].bst_date == date(2018, 1, 14)
|
||||||
|
|
||||||
|
|
||||||
def test_get_rate_for_letter_latest(notify_db, notify_db_session):
|
def test_get_rate_for_letter_latest(notify_db_session):
|
||||||
letter_rate = LetterRate(start_date=datetime(2017, 12, 1),
|
|
||||||
rate=Decimal(0.33),
|
|
||||||
crown=True,
|
|
||||||
sheet_count=1,
|
|
||||||
post_class='second')
|
|
||||||
|
|
||||||
dao_create_letter_rate(letter_rate)
|
|
||||||
letter_rate = LetterRate(start_date=datetime(2016, 12, 1),
|
|
||||||
end_date=datetime(2017, 12, 1),
|
|
||||||
rate=Decimal(0.30),
|
|
||||||
crown=True,
|
|
||||||
sheet_count=1,
|
|
||||||
post_class='second')
|
|
||||||
dao_create_letter_rate(letter_rate)
|
|
||||||
|
|
||||||
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
|
|
||||||
LetterRate.query.order_by(desc(LetterRate.start_date)).all()]
|
# letter rates should be passed into the get_rate function as a tuple of start_date, crown, sheet_count & rate
|
||||||
|
new_letter_rate = (datetime(2017, 12, 1), True, 1, Decimal(0.33))
|
||||||
|
old_letter_rate = (datetime(2016, 12, 1), True, 1, Decimal(0.30))
|
||||||
|
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)
|
||||||
assert rate == Decimal(0.33)
|
assert rate == Decimal(0.33)
|
||||||
|
|
||||||
|
|
||||||
def test_get_rate_for_sms_and_email(notify_db, notify_db_session):
|
def test_get_rate_for_sms_and_email(notify_db, notify_db_session):
|
||||||
letter_rate = LetterRate(start_date=datetime(2017, 12, 1),
|
|
||||||
rate=Decimal(0.33),
|
|
||||||
crown=True,
|
|
||||||
sheet_count=1,
|
|
||||||
post_class='second')
|
|
||||||
dao_create_letter_rate(letter_rate)
|
|
||||||
sms_rate = Rate(valid_from=datetime(2017, 12, 1),
|
sms_rate = Rate(valid_from=datetime(2017, 12, 1),
|
||||||
rate=Decimal(0.15),
|
rate=Decimal(0.15),
|
||||||
notification_type=SMS_TYPE)
|
notification_type=SMS_TYPE)
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ from tests.app.db import (
|
|||||||
create_template,
|
create_template,
|
||||||
create_notification,
|
create_notification,
|
||||||
create_rate,
|
create_rate,
|
||||||
create_letter_rate
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -223,18 +222,16 @@ def test_get_rates_for_billing(notify_db_session):
|
|||||||
create_rate(start_date=datetime.utcnow(), value=12, notification_type='email')
|
create_rate(start_date=datetime.utcnow(), value=12, notification_type='email')
|
||||||
create_rate(start_date=datetime.utcnow(), value=22, notification_type='sms')
|
create_rate(start_date=datetime.utcnow(), value=22, notification_type='sms')
|
||||||
create_rate(start_date=datetime.utcnow(), value=33, notification_type='email')
|
create_rate(start_date=datetime.utcnow(), value=33, notification_type='email')
|
||||||
create_letter_rate(start_date=datetime.utcnow())
|
|
||||||
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) == 1
|
assert len(letter_rates) == 10
|
||||||
|
|
||||||
|
|
||||||
def test_get_rate(notify_db_session):
|
def test_get_rate(notify_db_session):
|
||||||
create_rate(start_date=datetime.utcnow(), value=1.2, notification_type='email')
|
create_rate(start_date=datetime.utcnow(), value=1.2, notification_type='email')
|
||||||
create_rate(start_date=datetime.utcnow(), value=2.2, notification_type='sms')
|
create_rate(start_date=datetime.utcnow(), value=2.2, notification_type='sms')
|
||||||
create_rate(start_date=datetime.utcnow(), value=3.3, notification_type='email')
|
create_rate(start_date=datetime.utcnow(), value=3.3, notification_type='email')
|
||||||
create_letter_rate(start_date=datetime.utcnow(), rate=4.4)
|
|
||||||
non_letter_rates, letter_rates = get_rates_for_billing()
|
non_letter_rates, letter_rates = get_rates_for_billing()
|
||||||
rate = get_rate(non_letter_rates=non_letter_rates, letter_rates=letter_rates, notification_type='sms',
|
rate = get_rate(non_letter_rates=non_letter_rates, letter_rates=letter_rates, notification_type='sms',
|
||||||
date=datetime.utcnow())
|
date=datetime.utcnow())
|
||||||
@@ -245,7 +242,7 @@ def test_get_rate(notify_db_session):
|
|||||||
date=datetime.utcnow())
|
date=datetime.utcnow())
|
||||||
|
|
||||||
assert rate == 2.2
|
assert rate == 2.2
|
||||||
assert letter_rate == Decimal('4.4')
|
assert letter_rate == Decimal('0.3')
|
||||||
|
|
||||||
|
|
||||||
def test_fetch_monthly_billing_for_year(notify_db_session):
|
def test_fetch_monthly_billing_for_year(notify_db_session):
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
from datetime import datetime
|
|
||||||
|
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
from app.dao.letter_rate_dao import dao_create_letter_rate, get_letter_rates_for_daterange
|
|
||||||
from app.models import LetterRate
|
|
||||||
|
|
||||||
|
|
||||||
def test_dao_create_letter_rate(notify_db_session):
|
|
||||||
letter_rate = LetterRate(start_date=datetime(2017, 12, 1),
|
|
||||||
rate=0.33,
|
|
||||||
crown=True,
|
|
||||||
sheet_count=1,
|
|
||||||
post_class='second')
|
|
||||||
|
|
||||||
dao_create_letter_rate(letter_rate)
|
|
||||||
|
|
||||||
rates = LetterRate.query.all()
|
|
||||||
assert len(rates) == 1
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_letter_rates_for_daterange(notify_db_session):
|
|
||||||
letter_rate = LetterRate(start_date=datetime(2017, 12, 1),
|
|
||||||
rate=0.33,
|
|
||||||
crown=True,
|
|
||||||
sheet_count=1,
|
|
||||||
post_class='second')
|
|
||||||
|
|
||||||
dao_create_letter_rate(letter_rate)
|
|
||||||
letter_rate = LetterRate(start_date=datetime(2016, 12, 1),
|
|
||||||
end_date=datetime(2017, 12, 1),
|
|
||||||
rate=0.30,
|
|
||||||
crown=True,
|
|
||||||
sheet_count=1,
|
|
||||||
post_class='second')
|
|
||||||
|
|
||||||
dao_create_letter_rate(letter_rate)
|
|
||||||
|
|
||||||
results = get_letter_rates_for_daterange(date=datetime(2017, 12, 2), crown=True, sheet_count=1, post_class='second')
|
|
||||||
assert len(results) == 1
|
|
||||||
assert results[0].rate == Decimal('0.33')
|
|
||||||
@@ -18,7 +18,7 @@ from tests.app.db import (
|
|||||||
create_service,
|
create_service,
|
||||||
create_template,
|
create_template,
|
||||||
create_monthly_billing_entry,
|
create_monthly_billing_entry,
|
||||||
create_letter_rate)
|
)
|
||||||
|
|
||||||
FEB_2016_MONTH_START = datetime(2016, 2, 1)
|
FEB_2016_MONTH_START = datetime(2016, 2, 1)
|
||||||
FEB_2016_MONTH_END = datetime(2016, 2, 29, 23, 59, 59, 99999)
|
FEB_2016_MONTH_END = datetime(2016, 2, 29, 23, 59, 59, 99999)
|
||||||
@@ -154,7 +154,6 @@ def test_add_monthly_billing_for_single_month_populates_correctly(
|
|||||||
):
|
):
|
||||||
create_rate(start_date=JAN_2017_MONTH_START, value=0.0158, notification_type=SMS_TYPE)
|
create_rate(start_date=JAN_2017_MONTH_START, value=0.0158, notification_type=SMS_TYPE)
|
||||||
letter_template = sample_letter_template(sample_template.service)
|
letter_template = sample_letter_template(sample_template.service)
|
||||||
create_letter_rate(crown=False)
|
|
||||||
create_notification(
|
create_notification(
|
||||||
template=sample_template, created_at=JAN_2017_MONTH_START,
|
template=sample_template, created_at=JAN_2017_MONTH_START,
|
||||||
billable_units=1, rate_multiplier=2, status='delivered'
|
billable_units=1, rate_multiplier=2, status='delivered'
|
||||||
@@ -201,8 +200,8 @@ def test_add_monthly_billing_for_single_month_populates_correctly(
|
|||||||
"billing_units": 1,
|
"billing_units": 1,
|
||||||
"rate_multiplier": 1,
|
"rate_multiplier": 1,
|
||||||
"international": False,
|
"international": False,
|
||||||
"rate": 0.31,
|
"rate": 0.33,
|
||||||
"total_cost": 1 * 0.31
|
"total_cost": 1 * 0.33
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -286,7 +285,6 @@ def test_add_monthly_billing_with_multiple_rates_populate_correctly(
|
|||||||
create_notification(template=sample_email_template, created_at=JAN_2017_MONTH_START, status='delivered')
|
create_notification(template=sample_email_template, created_at=JAN_2017_MONTH_START, status='delivered')
|
||||||
create_notification(template=letter_template, created_at=JAN_2017_MONTH_START, status='delivered',
|
create_notification(template=letter_template, created_at=JAN_2017_MONTH_START, status='delivered',
|
||||||
billable_units=1)
|
billable_units=1)
|
||||||
create_letter_rate(start_date=JAN_2017_MONTH_START, crown=False)
|
|
||||||
|
|
||||||
create_or_update_monthly_billing(service_id=sample_template.service_id, billing_month=JAN_2017_MONTH_START)
|
create_or_update_monthly_billing(service_id=sample_template.service_id, billing_month=JAN_2017_MONTH_START)
|
||||||
|
|
||||||
@@ -329,8 +327,8 @@ def test_add_monthly_billing_with_multiple_rates_populate_correctly(
|
|||||||
"billing_units": 1,
|
"billing_units": 1,
|
||||||
"rate_multiplier": 1,
|
"rate_multiplier": 1,
|
||||||
"international": False,
|
"international": False,
|
||||||
"rate": 0.31,
|
"rate": 0.33,
|
||||||
"total_cost": 0.31
|
"total_cost": 0.33
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from app.models import (
|
|||||||
Rate,
|
Rate,
|
||||||
SMS_TYPE,
|
SMS_TYPE,
|
||||||
)
|
)
|
||||||
from tests.app.db import create_notification, create_rate, create_letter_rate, create_template, create_service
|
from tests.app.db import create_notification, create_rate, create_template, create_service
|
||||||
|
|
||||||
|
|
||||||
def test_get_rates_for_daterange(notify_db, notify_db_session):
|
def test_get_rates_for_daterange(notify_db, notify_db_session):
|
||||||
@@ -217,7 +217,6 @@ def test_get_monthly_billing_data_where_start_date_before_rate_returns_empty(
|
|||||||
def test_billing_letter_data_per_month_query(
|
def test_billing_letter_data_per_month_query(
|
||||||
notify_db_session
|
notify_db_session
|
||||||
):
|
):
|
||||||
create_letter_rate()
|
|
||||||
service = create_service()
|
service = create_service()
|
||||||
template = create_template(service=service, template_type='letter')
|
template = create_template(service=service, template_type='letter')
|
||||||
create_notification(template=template, billable_units=1, created_at=datetime(2017, 2, 1, 13, 21),
|
create_notification(template=template, billable_units=1, created_at=datetime(2017, 2, 1, 13, 21),
|
||||||
@@ -232,5 +231,5 @@ def test_billing_letter_data_per_month_query(
|
|||||||
end_date=datetime(2017, 2, 28))
|
end_date=datetime(2017, 2, 28))
|
||||||
|
|
||||||
assert len(results) == 1
|
assert len(results) == 1
|
||||||
assert results[0].rate == 0.31
|
assert results[0].rate == 0.3
|
||||||
assert results[0].billing_units == 3
|
assert results[0].billing_units == 3
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ from app.models import (
|
|||||||
SMS_TYPE,
|
SMS_TYPE,
|
||||||
KEY_TYPE_NORMAL,
|
KEY_TYPE_NORMAL,
|
||||||
AnnualBilling,
|
AnnualBilling,
|
||||||
LetterRate,
|
|
||||||
InvitedOrganisationUser,
|
InvitedOrganisationUser,
|
||||||
FactBilling,
|
FactBilling,
|
||||||
FactNotificationStatus,
|
FactNotificationStatus,
|
||||||
@@ -475,28 +474,6 @@ def create_annual_billing(
|
|||||||
return annual_billing
|
return annual_billing
|
||||||
|
|
||||||
|
|
||||||
def create_letter_rate(
|
|
||||||
start_date=datetime(2017, 1, 1, 00, 00, 00),
|
|
||||||
end_date=None,
|
|
||||||
sheet_count=1,
|
|
||||||
rate=0.31,
|
|
||||||
crown=True,
|
|
||||||
post_class='second'
|
|
||||||
):
|
|
||||||
rate = LetterRate(
|
|
||||||
start_date=start_date,
|
|
||||||
end_date=end_date,
|
|
||||||
sheet_count=sheet_count,
|
|
||||||
rate=rate,
|
|
||||||
crown=crown,
|
|
||||||
post_class=post_class
|
|
||||||
)
|
|
||||||
db.session.add(rate)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return rate
|
|
||||||
|
|
||||||
|
|
||||||
def create_organisation(name='test_org_1', active=True):
|
def create_organisation(name='test_org_1', active=True):
|
||||||
data = {
|
data = {
|
||||||
'name': name,
|
'name': name,
|
||||||
|
|||||||
@@ -105,7 +105,8 @@ def notify_db_session(notify_db):
|
|||||||
"notification_status_types",
|
"notification_status_types",
|
||||||
"service_permission_types",
|
"service_permission_types",
|
||||||
"auth_type",
|
"auth_type",
|
||||||
"invite_status_type"]:
|
"invite_status_type",
|
||||||
|
"letter_rates"]:
|
||||||
notify_db.engine.execute(tbl.delete())
|
notify_db.engine.execute(tbl.delete())
|
||||||
notify_db.session.commit()
|
notify_db.session.commit()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user