mirror of
https://github.com/GSA/notifications-api.git
synced 2026-08-18 05:28:49 -04:00
1. For both email and sms, store [] in monthly_totals if there is no billing data (no notifications sent etc.) and return this via the API 2. General refactoring of indentation
126 lines
4.1 KiB
Python
126 lines
4.1 KiB
Python
from datetime import datetime
|
|
|
|
from sqlalchemy import func
|
|
|
|
|
|
from app import db
|
|
from app.dao.dao_utils import transactional
|
|
from app.dao.date_util import get_month_start_and_end_date_in_utc, get_financial_year
|
|
from app.dao.notification_usage_dao import get_billing_data_for_month
|
|
from app.models import (
|
|
SMS_TYPE,
|
|
EMAIL_TYPE,
|
|
MonthlyBilling,
|
|
NotificationHistory
|
|
)
|
|
from app.statsd_decorators import statsd
|
|
from app.utils import convert_utc_to_bst
|
|
|
|
|
|
def get_service_ids_that_need_billing_populated(start_date, end_date):
|
|
return db.session.query(
|
|
NotificationHistory.service_id
|
|
).filter(
|
|
NotificationHistory.created_at >= start_date,
|
|
NotificationHistory.created_at <= end_date,
|
|
NotificationHistory.notification_type.in_([SMS_TYPE, EMAIL_TYPE]),
|
|
NotificationHistory.billable_units != 0
|
|
).distinct().all()
|
|
|
|
|
|
def create_or_update_monthly_billing(service_id, billing_month):
|
|
start_date, end_date = get_month_start_and_end_date_in_utc(billing_month)
|
|
_update_monthly_billing(service_id, start_date, end_date, SMS_TYPE)
|
|
_update_monthly_billing(service_id, start_date, end_date, EMAIL_TYPE)
|
|
|
|
|
|
def _monthly_billing_data_to_json(billing_data):
|
|
results = []
|
|
if billing_data:
|
|
# total cost must take into account the free allowance.
|
|
# might be a good idea to capture free allowance in this table
|
|
results = [{
|
|
"billing_units": x.billing_units,
|
|
"rate_multiplier": x.rate_multiplier,
|
|
"international": x.international,
|
|
"rate": x.rate,
|
|
"total_cost": (x.billing_units * x.rate_multiplier) * x.rate
|
|
} for x in billing_data]
|
|
return results
|
|
|
|
|
|
@transactional
|
|
def _update_monthly_billing(service_id, start_date, end_date, notification_type):
|
|
billing_data = get_billing_data_for_month(
|
|
service_id=service_id,
|
|
start_date=start_date,
|
|
end_date=end_date,
|
|
notification_type=notification_type
|
|
)
|
|
monthly_totals = _monthly_billing_data_to_json(billing_data)
|
|
row = get_monthly_billing_entry(service_id, start_date, notification_type)
|
|
if row:
|
|
row.monthly_totals = monthly_totals
|
|
row.updated_at = datetime.utcnow()
|
|
else:
|
|
row = MonthlyBilling(
|
|
service_id=service_id,
|
|
notification_type=notification_type,
|
|
monthly_totals=monthly_totals,
|
|
start_date=start_date,
|
|
end_date=end_date
|
|
)
|
|
|
|
db.session.add(row)
|
|
|
|
|
|
def get_monthly_billing_entry(service_id, start_date, notification_type):
|
|
entry = MonthlyBilling.query.filter_by(
|
|
service_id=service_id,
|
|
start_date=start_date,
|
|
notification_type=notification_type
|
|
).first()
|
|
|
|
return entry
|
|
|
|
|
|
@statsd(namespace="dao")
|
|
def get_yearly_billing_data_for_date_range(
|
|
service_id, start_date, end_date, notification_types
|
|
):
|
|
results = db.session.query(
|
|
MonthlyBilling.notification_type,
|
|
MonthlyBilling.monthly_totals,
|
|
MonthlyBilling.start_date,
|
|
).filter(
|
|
MonthlyBilling.service_id == service_id,
|
|
MonthlyBilling.start_date >= start_date,
|
|
MonthlyBilling.end_date <= end_date,
|
|
MonthlyBilling.notification_type.in_(notification_types)
|
|
).order_by(
|
|
MonthlyBilling.notification_type
|
|
).all()
|
|
|
|
return results
|
|
|
|
|
|
@statsd(namespace="dao")
|
|
def get_monthly_billing_by_notification_type(service_id, billing_month, notification_type):
|
|
billing_month_in_bst = convert_utc_to_bst(billing_month)
|
|
start_date, _ = get_month_start_and_end_date_in_utc(billing_month_in_bst)
|
|
return get_monthly_billing_entry(service_id, start_date, notification_type)
|
|
|
|
|
|
@statsd(namespace="dao")
|
|
def get_billing_data_for_financial_year(service_id, year, notification_types=[SMS_TYPE, EMAIL_TYPE]):
|
|
# Update totals to the latest so we include data for today
|
|
now = convert_utc_to_bst(datetime.utcnow())
|
|
create_or_update_monthly_billing(service_id=service_id, billing_month=now)
|
|
|
|
start_date, end_date = get_financial_year(year)
|
|
|
|
results = get_yearly_billing_data_for_date_range(
|
|
service_id, start_date, end_date, notification_types
|
|
)
|
|
return results
|