Merge pull request #3193 from alphagov/populate-annual-billing-2021

Populate annual billing for 2021
This commit is contained in:
Rebecca Law
2021-03-31 07:58:16 +01:00
committed by GitHub
3 changed files with 176 additions and 31 deletions

View File

@@ -12,6 +12,7 @@ from flask import current_app, json
from notifications_utils.recipients import RecipientCSV
from notifications_utils.statsd_decorators import statsd
from notifications_utils.template import SMSMessageTemplate
from sqlalchemy import and_
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm.exc import NoResultFound
@@ -29,6 +30,7 @@ from app.celery.tasks import process_row, record_daily_sorted_counts
from app.config import QueueNames
from app.dao.annual_billing_dao import (
dao_create_or_update_annual_billing_for_year,
set_default_free_allowance_for_service,
)
from app.dao.fact_billing_dao import (
delete_billing_data_for_service_for_day,
@@ -67,6 +69,7 @@ from app.models import (
NOTIFICATION_CREATED,
PROVIDERS,
SMS_TYPE,
AnnualBilling,
Domain,
EmailBranding,
LetterBranding,
@@ -234,36 +237,6 @@ def fix_notification_statuses_not_in_sync():
result = db.session.execute(subq_hist).fetchall()
@notify_command(name='populate-annual-billing')
@click.option('-y', '--year', required=True, type=int,
help="""The year to populate the annual billing data for, i.e. 2019""")
def populate_annual_billing(year):
"""
add annual_billing for given year.
"""
sql = """
Select id from services where active = true
except
select service_id
from annual_billing
where financial_year_start = :year
"""
services_without_annual_billing = db.session.execute(sql, {"year": year})
for row in services_without_annual_billing:
latest_annual_billing = """
Select free_sms_fragment_limit
from annual_billing
where service_id = :service_id
order by financial_year_start desc limit 1
"""
free_allowance_rows = db.session.execute(latest_annual_billing, {"service_id": row.id})
free_allowance = [x[0]for x in free_allowance_rows]
print("create free limit of {} for service: {}".format(free_allowance[0], row.id))
dao_create_or_update_annual_billing_for_year(service_id=row.id,
free_sms_fragment_limit=free_allowance[0],
financial_year_start=int(year))
@notify_command(name='list-routes')
def list_routes():
"""List URLs of all application routes."""
@@ -877,3 +850,67 @@ def process_row_from_job(job_id, job_row_number):
notification_id = process_row(row, template, job, job.service)
current_app.logger.info("Process row {} for job {} created notification_id: {}".format(
job_row_number, job_id, notification_id))
@notify_command(name='populate-annual-billing-with-the-previous-years-allowance')
@click.option('-y', '--year', required=True, type=int,
help="""The year to populate the annual billing data for, i.e. 2019""")
def populate_annual_billing_with_the_previous_years_allowance(year):
"""
add annual_billing for given year.
"""
sql = """
Select id from services where active = true
except
select service_id
from annual_billing
where financial_year_start = :year
"""
services_without_annual_billing = db.session.execute(sql, {"year": year})
for row in services_without_annual_billing:
latest_annual_billing = """
Select free_sms_fragment_limit
from annual_billing
where service_id = :service_id
order by financial_year_start desc limit 1
"""
free_allowance_rows = db.session.execute(latest_annual_billing, {"service_id": row.id})
free_allowance = [x[0]for x in free_allowance_rows]
print("create free limit of {} for service: {}".format(free_allowance[0], row.id))
dao_create_or_update_annual_billing_for_year(service_id=row.id,
free_sms_fragment_limit=free_allowance[0],
financial_year_start=int(year))
@notify_command(name='populate-annual-billing-with-defaults')
@click.option('-y', '--year', required=True, type=int,
help="""The year to populate the annual billing data for, i.e. 2021""")
@click.option('-m', '--missing-services-only', default=True, type=bool,
help="""If true then only populate services missing from annual billing for the year.
If false populate the default values for all active services.""")
def populate_annual_billing_with_defaults(year, missing_services_only):
"""
Add or update annual billing with free allowance defaults for all active services.
The default free allowance limits are in: app/dao/annual_billing_dao.py:57.
If missing_services_only is true then only add rows for services that do not have annual billing for that year yet.
This is useful to prevent overriding any services that have a free allowance that is not the default.
If missing_services_only is false then add or update annual billing for all active services.
This is useful to ensure all services start the new year with the correct annual billing.
"""
if missing_services_only:
active_services = Service.query.filter(
Service.active
).outerjoin(
AnnualBilling, and_(Service.id == AnnualBilling.service_id, AnnualBilling.financial_year_start == year)
).filter(
AnnualBilling.id == None # noqa
).all()
else:
active_services = Service.query.filter(
Service.active
).all()
for service in active_services:
set_default_free_allowance_for_service(service, year)

View File

@@ -1,3 +1,5 @@
from flask import current_app
from app import db
from app.dao.dao_utils import transactional
from app.dao.date_util import get_current_financial_year_start_year
@@ -49,3 +51,58 @@ def dao_get_all_free_sms_fragment_limit(service_id):
return AnnualBilling.query.filter_by(
service_id=service_id,
).order_by(AnnualBilling.financial_year_start).all()
def set_default_free_allowance_for_service(service, year_start=None):
default_free_sms_fragment_limits = {
'central': {
2020: 250_000,
2021: 150_000,
},
'local': {
2020: 25_000,
2021: 25_000,
},
'nhs_central': {
2020: 250_000,
2021: 150_000,
},
'nhs_local': {
2020: 25_000,
2021: 25_000,
},
'nhs_gp': {
2020: 25_000,
2021: 10_000,
},
'emergency_service': {
2020: 25_000,
2021: 25_000,
},
'school_or_college': {
2020: 25_000,
2021: 10_000,
},
'other': {
2020: 25_000,
2021: 10_000,
},
}
if not year_start:
year_start = get_current_financial_year_start_year()
if year_start < 2020:
year_start = 2020
if year_start > 2021:
year_start = 2021
if service.organisation_type:
free_allowance = default_free_sms_fragment_limits[service.organisation_type][year_start]
else:
current_app.logger.info(f"no organisation type for service {service.id}. Using other default of "
f"{default_free_sms_fragment_limits['other'][year_start]}")
free_allowance = default_free_sms_fragment_limits['other'][year_start]
dao_create_or_update_annual_billing_for_year(
service.id,
free_allowance,
year_start
)